Types of Inner Classes in Java
In this article, information about Inner Classes in Java, including Local Classes and Anonymous Classes, will be shared by Mangcoding. Hopefully, this explanation can be understood easily by those who are currently learning Java. Let’s dive in!
What is an Inner Class?
An inner class is defined as a class that is not at the top level but rather declared inside another class (Outer class).
It must be remembered that an instance object of the outer class is required for an inner class to access its methods or fields.
Since an instance of the top-level class is used by the inner class, its members are not allowed to be declared as static.
class OuterClass { ... class InnerClass { ... } }
In Java, two main forms of inner classes are provided:
-
Local Classes
-
Anonymous Classes
1. Local Classes
A local class is declared within a block, whether inside a method, loop, or control flow. Typically, they are often used within methods
a. Declaring a Local Class
A local class can be declared inside a block such as an expression, statement, or method body. For example, a local class may be placed inside a method, a for loop, or even inside an if statement. The following example is provided:
package com.wordpress.bmadi.morenestedclass;
public class DemoLocalClass {
String format = "[^0-9]";
public static void validatePhoneNumber(String phoneNumber) {
final int numberLength = 12;
class PhoneNumber {
String formattedNumber = null;
PhoneNumber(String phoneNumber) {
String currentNumber = phoneNumber.replaceAll(format, "");
if (currentNumber.length() == numberLength) {
formattedNumber = currentNumber;
} else {
formattedNumber = null;
}
}
public String getNumber() {
return formattedNumber;
}
public void printOriginalNumber() {
System.out.println("Original Number : " + phoneNumber);
}
}
PhoneNumber myNumber = new PhoneNumber(phoneNumber);
myNumber.printOriginalNumber();
if (myNumber.getNumber() == null) {
System.out.println("Number is invalid");
} else {
System.out.println("Number : " + myNumber.getNumber());
}
}
public static void main(String[] args) {
validatePhoneNumber("0858-6722-9783");
}
}
In the program above, the local class PhoneNumber is declared inside the method validatePhoneNumber. The phone number is validated based on the predefined format and length.
b. Accessing class members
A local class can access class members from its main class. Local variables can also be accessed, but access is only allowed if they are declared as final, take a look at the image below!
PhoneNumber(String phoneNumber) {
int numberLength = 10;
String currentNumber = phoneNumber.replaceAll(format, "");
if (currentNumber.length() == numberLength) {
formatNumber = currentNumber;
} else {
formatNumber = null;
}
}
The code above changes the value of the variable numberLength, which is marked as final. The code snippet forces a change in its value from 12 to 10.
c. Similarities between inner class and local class
A local class is similar to an inner class because they cannot be declared using static members. A local class inside a static method behaves similarly.
For example, the PhoneNumber class declared inside the static method validatePhoneNumber can only access static members of the class where it is declared.
An anonymous class is defined as a class without a name. It is often created for one-time use and is mostly applied to implement interfaces or abstract classes directly.
Since no name is given to an anonymous class, the name of the interface or abstract class being implemented is used
a. Declaring an anonymous class
An anonymous class is different in that it is not declared inside another class but rather within an expression, similar to how we declare a class inside an expression. Take a look at the image below!
package com.wordpress.bmadi.morenestedclass;
public class DemoHelloIndoClass {
interface HelloIndo {
public void greet();
public void greetSomeone(String someone);
}
public void sayHelloIndo() {
class IndoGreeting implements HelloIndo {
String name = "indonesia";
public void greet() {
greetSomeone("Indonesia");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
}
}
HelloIndo IndoGreeting = new IndoGreeting();
HelloIndo jawaGreeting = new HelloIndo() {
String name = "Jawa";
public void greet() {
greetSomeone("Jawa");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hay " + name);
}
};
IndoGreeting.greet();
IndoGreeting.greetSomeone("Sandi");
jawaGreeting.greet();
IndoGreeting.greetSomeone("Jumadi");
public static void main(String[] args) {
DemoHelloIndoClass myApp = new DemoHelloIndoClass();
myApp.sayHelloIndo()
b. Anonymous Class Syntax
As previously explained, an anonymous class is declared within an expression. Take a look at the code below!
HelloIndo jawaGreeting = new HelloIndo() {
String name = "Jawa";
public void greet() {
greetSomeone("Jawa");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hay " + name);
}
};
Anonymous Class Components An anonymous class contains several supporting components, including :
- The new operator
- The name of the interface or the class being extended (in the example above, the anonymous class implements the HelloIndo interface)
- Parentheses that may contain arguments or other elements, similar to a normal class. However, when using an interface, we cannot use a constructor, so we leave the parentheses empty, as shown in the example above.
- The body of the class
c. Accessing Local Variables Based on Scope and Accessing Members of the Anonymous Class
Similar to a local class, an anonymous class can capture variables. It follows the same rules regarding accessing local variables based on the scope of the enclosing class, such as :
- An anonymous class can access members of the class it is enclosed in.
- It cannot access local variables from the enclosing class’s scope unless those variables are declared as final or effectively final.
- Like a nested class, an anonymous class can declare a variable with the same name (shadowing) as a variable in the enclosing class scope. (For more details on shadowing, refer to this article.)
Anonymous Class Restrictions, There are certain restrictions when using an anonymous class :
- We cannot declare static initializers or interface members within an anonymous class.
- We can only declare static members if they are constant variables.
Additional Features of Anonymous Classes, An anonymous class can also include :
- Fields
- Extra method
- Instance initializer
- Local class
d. Example of an Anonymous Class
public class DemoAnonymousClass {
public static void main(String[] args) {
Thread anonymous = new Thread() {
@Override
public void run() {
System.out.println("This is example anonymous class in Java");
}
};
anonymous.start();
}
}
The program code above means : Declaring an anonymous class that implements the Thread interface and calling the Thread object method using the start method.
That’s the explanation of Types of Inner Classes in Java that Mangcoding can share. Hopefully, this article is useful and provides new insights for you. If you have constructive feedback or suggestions, feel free to leave a comment or contact us via email and Mangcoding’s social media.