内部类一般有两种,成员内部类和匿名内部类,运行后都会有单独的.class文件产生;
1.成员内部类
- 成员内部类,一般指类中再嵌套一个类,称为外部类和内部类;
- 内部类只能服务于外部类,只能在外部类中实例化;
- 内部类可以调用外部类的成员变量和方法,即使是私有的;
- 此时系统自动补充了外部类.this.变量的操作
//Mom.java
package com.ott.autotest;
public class Mom {
private int a = 4;
public void sayHi(){
System.out.println("外部类方法sayHi()");
}
public void handleInner(){
Child c = new Child();
c.print();
}
public class Child {
public void print(){
System.out.println(a);
sayHi();
}
}
}
//Test.java
package com.ott.autotest;
public class Test {
public static void main(String[] args) {
Mom m = new Mom();
m.handleInner();
}
}
//4
//外部类方法sayHi()
- 此时执行后,会出现三个.class文件
- Mom.class
- Mom$Child.class (成员内部类单独字节码文件)
- Test.class
2.匿名内部类
- 匿名内部类一般是服务于adstract抽象方法的;
- 当抽象类只使用一次时,可用匿名内部类的方式自动创建派生类及重写抽象方法;
- 匿名内部类也是会产生自己的.class文件的
- 所以此时外部类的变量默认是final形式不可在内部类修改的
- 因为有单独的.class文件,在内部类修改也是修改的变量的副本,所以为了数据的安全性和可预测性,Java要求在匿名内部类中引用的局部变量必须声明为final或effectively final;
//Aoo.java
package com.autotest.test2;
public abstract class Aoo {
public abstract void show();
}
//Test.java
package com.autotest.test2;
public class Test {
public static void main(String[] args) {
int c = 34;
Aoo a = new Aoo() {
@Override
public void show() {
System.out.println("匿名内部类");
System.out.println(c);
//c = 66;
//Variable 'c' is accessed from within inner class, needs to be final or effectively final
}
};
a.show();
}
}
//匿名内部类
//34
- 此时执行结束后,会有三个.class文件出现;
- Test.class
- Aoo.class
- Test$1.class (匿名内部类单独的字节码文件)