Detailed explanation of internal classes and internal interfaces in Java
brief introduction
Generally speaking, when we create classes and interfaces, each class is a file, and each interface is a file. However, sometimes for convenience or some special reasons, Java doesn't mind writing multiple classes and interfaces in one file. This leads to the internal classes and interfaces we want to talk about today.
Inner class
Let's talk about inner classes first. Inner classes are classes defined in classes. A class in a class can be regarded as an attribute of a class. An attribute can be static or non static. The inner class can also be defined in the method of the class. Plus the anonymous class, there are five kinds of inner classes in total.
Static inner class
We define a static class inside the class, as shown below:
@Slf4j
public class StaticInnerClass {
static class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
StaticInnerClass.Inner inner = new StaticInnerClass.Inner();
inner.print();
}
}
Because the static variable can be accessed directly according to the class name, we use new StaticInnerClass Inner() to instantiate the inner class.
Non static inner class
The classes defined in class can also be non static, as shown below:
@Slf4j
public class InnerClass {
class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
InnerClass.Inner inner = new InnerClass().new Inner();
inner.print();
}
}
To access the variables of the class, you need to instantiate the external class and then the internal class: new innerclass() new Inner()。
Note that we need to use two new here.
Static method inner class
We can define a class in a static method. This class is actually equivalent to a variable in the method. Of course, this variable cannot be static. Let's look at the following example:
@Slf4j
public class StaticMethodInnerClass {
private static String x = "static x";
public static void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
StaticMethodInnerClass.print();
}
}
Method, we can't instantiate it externally.
Inner class of non static method
Similarly, non static methods can also define internal classes:
@Slf4j
public class MethodInnerClass {
private String x = "non static x";
public void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
new MethodInnerClass().print();
}
}
Note that you need to instantiate an external class before you can continue calling.
Anonymous class
The last one, anonymous class, is a class that is instantiated directly when needed. We have encountered anonymous classes many times. For example, when building sortedset, we can pass in a custom comparator. We can implement anonymous classes or directly use lambda expressions.
public class AnonymousClass {
public static void main(String[] args) {
SortedSet sortedSet1 = new ConcurrentSkipListSet(new Comparator(){
@Override
public int compare(Object o1,Object o2) {
return 0;
}
});
SortedSet sortedSet2 = new ConcurrentSkipListSet((o1,o2) -> 0);
}
}
Internal interface
Inner interface refers to the interface defined in the interface. The most common is the entry in the map:
public interface Map<K,V> {
interface Entry<K,V> {
K getKey();
}
The internal interface here must be static because the interface cannot be instantiated. Therefore, in order to access the interface in the interface, it must be defined as static. If not specified, the default is static.
Let's look at the implementation of this internal interface:
public class MapImpl implements Map.Entry{
@Override
public Object getKey() {
return 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public Object setValue(Object value) {
return null;
}
}