在Java中,可以将一个类声明在另一个类的内部,这个类就是嵌套类。嵌套类可以分为两类:静态(static)和非静态(non-static)。被static修饰的嵌套类称为静态嵌套类(static nested classes)。非静态嵌套类称为内部类(inner classes)。如:
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
嵌套类是外部封装类的成员,使用member level访问修饰符(private,public,protected,package-private)。而外部类使用top level访问修饰符(public,package-private)。
访问控制:Java访问控制 - 简书
一、静态嵌套类
与类方法、类变量相似,静态嵌套类和外部类相关。与静态类方法相似,静态嵌套类不能直接引用外部类的实例变量和实例方法,只能对象引用来访问。从行为看,静态嵌套类就是一个外部类(或top-level类)。
静态嵌套类访问:OuterClass.StaticNestedClass
创建静态嵌套类对象:OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
二、内部类
和实例方法、实例变量相似,内部类和它的外部封装类的实例相关。内部类可以直接访问外部封装类实例的方法和域。同样,内部类和实例相关,所以不能定义自己的静态成员。
一个内部类的实例只能在一个外部类实例中存在,因此,要实例化一个内部类就必须先实例化外部类,再在外部类的对象中创建一个内部类的对象。内部类实例的创建:OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
此外,还有两种特殊的内部类:局部类(local classes)和匿名类(anonymous classes)。
三、屏蔽
public class Outer{
public int x = 0;
class Inner {
public int x = 1;
void method(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("Outer.this.x = " + Outer.this.x);
}
}
}
上边例子中声明了三个名为x的变量:Outer类的成员变量、Inner类的成员变量、method方法的参数。内层的变量会屏蔽外层的变量,则使用x引用method参数;使用this.x引用Inner类的成员变量;使用Outer.this.x引用Outer类的成员变量。
四、序列化
Java编译器编译内部类的时候会生成源文件中没有的结构,而不同的编译器实现不同,生成的.class文件就会有所不同。如果序列化和反序列化使用不同的JRE可能会出问题,因此,不建议对内部类(包括局部和匿名内部类)序列化。
Reference:Nested Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects)