本文转自这里
在类内部定义的类就是嵌套类(nested class),如:
class OuterClass {
...
class NestedClass {
...
}
}
嵌套类分为两种:静态的(static)和非静态(non-static)的,非静态嵌套类又称为内部类(inner class)
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
嵌套类是作为外部类成员变量存在的,因此可以像成员变量一样声明成public,private,protected或者包可见的。内部类可以访问所在的类的所有成员变量,即使是private的,而静态嵌套类不能访问成员变量。
使用嵌套类的原因
- 如果某个类只在一个类中用到,那么前者就可以声明为嵌套类
- 可以访问private,增加了封装读
- 声明在同一个类中,增加了可读性
静态嵌套类
类似于静态方法,不能直接访问实例变量和非静态方法。和外部类一样,也要通过对象访问实例变量和方法,只不过嵌套在了别的类中。
//Static nested classes are accessed using the enclosing class name
OuterClass.StaticNestedClass
//create an object for the static nested class
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
内部类
可以直接访问外部类的成员变量和方法,是作为一个实例存在于外部类中的,因此内部类中不能定义静态成员变量和方法。
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
投影(shadowing)
如果内部类的成员变量或方法的形参与所处外部作用域名称相同,那么就会产生投影,不能直接访问被投影的变量。
如何访问被投影的变量:
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
输出结果:
x = 23
this.x = 1
ShadowTest.this.x = 0
序列化
内部类的序列化是强烈不推荐的,因为可能会因为JRE的实现方式不同产生兼容性问题。