In Java, an inner class is a class that is defined inside another class. Inner classes can be used to logically group classes and interfaces in one place, improve encapsulation and maintainability of code, and provide a way to access private members of the outer class from within the inner class.
There are four types of inner classes in Java:
- Non-static inner class (also called inner class)
- Static nested class
- Local inner class
- Anonymous inner class
1. Non-static inner class (also called inner class)
A non-static inner class is a class that is defined inside another class without using the static
keyword. It has access to all members of the outer class, including private members. Here’s an example:
public class OuterClass { private int x = 10; class InnerClass { public void printX() { System.out.println("x = " + x); } } } public class Main { public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.new InnerClass(); inner.printX(); } }
In the above example, the OuterClass
has a non-static inner class called InnerClass
, which has access to the private member x
. The Main
class creates an instance of the OuterClass
and then creates an instance of the InnerClass
using the new
keyword and the outer.new
syntax. Finally, it calls the printX()
method on the InnerClass
instance.
2. Static nested class
A static nested class is a class that is defined inside another class using the static
keyword. It does not have access to the members of the outer class, unless they are static. Here’s an example:
public class OuterClass { private static int x = 10; static class NestedClass { public void printX() { System.out.println("x = " + x); } } } public class Main { public static void main(String[] args) { OuterClass.NestedClass nested = new OuterClass.NestedClass(); nested.printX(); } }
In the above example, the OuterClass
has a static nested class called NestedClass
, which can access the static member x
. The Main
class creates an instance of the NestedClass
using the OuterClass.NestedClass
syntax and calls the printX()
method on it.
3. Local inner class
A local inner class is a class that is defined inside a method or a block of code. It has access to the final or effectively final variables of the enclosing method or block. Here’s an example:
public class OuterClass { public void printMessage(final String message) { class LocalInnerClass { public void print() { System.out.println(message); } } LocalInnerClass inner = new LocalInnerClass(); inner.print(); } } public class Main { public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.printMessage("Hello, world!"); } }
In the above example, the OuterClass
has a method called printMessage()
that defines a local inner class called LocalInnerClass
, which has access to the message
parameter. The print()
method of the LocalInnerClass
is called to print the message.
4. Anonymous inner class
An anonymous inner class is a class that is defined inside a method or a block of code without a name. It is typically used to create an instance of an interface or an abstract class with a single method.
Here’s an example of an anonymous inner class that implements the Runnable
interface:
public class Main { public static void main(String[] args) { Runnable runnable = new Runnable() { public void run() { System.out.println("Hello, world!"); } }; Thread thread = new Thread(runnable); thread.start(); } }
In the above example, an anonymous inner class is used to create an instance of the Runnable
interface with a single run()
method that prints “Hello, world!” to the console. The anonymous inner class is defined inside the main()
method using the new
keyword and the Runnable
interface.
The anonymous inner class is then passed as an argument to the Thread
constructor, which takes an instance of the Runnable
interface. Finally, the start()
method is called on the Thread
instance to start a new thread and execute the run()
method of the anonymous inner class.
Anonymous inner classes can also be used to create instances of abstract classes with a single abstract method. Here’s an example:
abstract class MyAbstractClass { public abstract void printMessage(String message); } public class Main { public static void main(String[] args) { MyAbstractClass myObject = new MyAbstractClass() { public void printMessage(String message) { System.out.println(message); } }; myObject.printMessage("Hello, world!"); } }
In the above example, an anonymous inner class is used to create an instance of the MyAbstractClass
abstract class with a single printMessage()
method that prints the message passed as an argument to the console. The anonymous inner class is defined inside the main()
method using the new
keyword and the MyAbstractClass
abstract class.
The anonymous inner class is then assigned to a variable of type MyAbstractClass
. Finally, the printMessage()
method of the anonymous inner class is called on the myObject
instance to print “Hello, world!” to the console.