一,内部类
定义在另一个类中的类
1.为什么使用内部类
①内部类可以访问该类所在作用域中的数据
②内部类可以对同一包中其他类隐藏起来
③不想编写大量代码时,内部类比较快捷
//使用内部类访问对象状态
public class Outer {
private int abc = 10;
public void outerMethod() {
System.out.println("In Outer class");
Inner inner = new Inner();
inner.innerMethod();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.outerMethod();
}
private class Inner {
public void innerMethod() {
System.out.println("The var own in Outer is " + abc);
}
}
}
运行结果:10
原因:非静态内部类对象会隐式地持有一个外部类对象的引用,我们假设这个引用名为outer,那么实际上内部类的innerMethod方法是这样子的
public void innerMethod() {
System.out.println("The var own in Outer is " + outer.own);
}
编译器会修改Inner类的构造器,添加一个外部类Outer的引用作为参数,大概是这个样子
public Inner(Outer outer) {
this.outer = outer;
}
注意: 我们希望一个静态域只有一个实例 ,不过对于每个外部对象,会分别有一个单独的内部类实例。如果这个域不是fianl,它可能是不唯一的。因为可以通过外部内进行更改,故需要设置为final 的
原因:用final修饰实际上就是为了保护数据的一致性
因为将数据拷贝完成后,如果不用final修饰,则原先的局部变量可以发生变化。这里到了问题的核心了,如果局部变量发生变化后,匿名内部类是不知道的(因为他只是拷贝了局不变量的值,并不是直接使用的局部变量)
例子:原先局部变量指向的是对象A,在创建匿名内部类后,匿名内部类中的成员变量也指向A对象。但过了一段时间局部变量的值指向另外一个B对象,但此时匿名内部类中还是指向原先的A对象。那么程序再接着运行下去,可能就会导致程序运行的结果与预期不同
2.局部内部类
定义的位置:在一个类的成员方法中。或者说,定义在一个成员方法的中的类就是局部内部类
①不能使用任何的访问修饰符。
②会生成两个.class文件,一个是Outer.class ,另一个是Outer$LocalInner.class。
③局部内部类只能访问方法中声明的final类型的变量