引言
基于JDK1.8分析Java的内部类以及内部类的使用方法。
1、内部类介绍
内部类分为4种:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
思维导图:
1.1 成员内部类
在写法上与成员变量相似,直接写在类里。
内部类的定义示例:
public class OutClass {
int a = 1;
class InnerClass {
int a = 2;
public void printA() {
System.out.println(a);
System.out.println(this.a);
System.out.println(OutClass.this.a);
}
}
}
成员内部类(非静态内部类)有几点需要注意:
- 如果在内部类中访问外部类的成员变量或者方法,需要注意访问格式。
- 在成员内部类中不能定义没有被final修饰的静态成员变量或静态方法,在IDEA下会直接提示错误:内部类不能有静态声明;因为
- 成员内部类的访问权限与成员变量相同。
测试一下:
public class Main {
public static void main(String[] args) {
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass = outClass.new InnerClass();
innerClass.printA();
}
}
运行结果:
parameter a = 2
parameter a = 2
parameter a = 1
Process finished with exit code 0
由此可以得知,如果在内部类中定义了与外部类中成员变量同名的成员变量, 直接通过变量名访问和通过“this.成员变量”访问的都是内部类的成员变量;访问外部类的成员变量的格式应该是“外部类名称.this.成员变量”。
除此之外,还需要注意的一点是,由于实例化一个内部类必须要 先实例化一个外部类对象,再通过外部类对象去实例化出内部类对象(内部类对象在实例化之前必须要实例化外部类对象,因为内部类对象可以访问外部类的成员变量,只有外部类实例化之后外部类的成员变量才有意义)。因此,一个内部类对象会持有一个外部类对象的引用。如果内部类对象的方法还没有执行完,那么外部类对象就不能被虚拟机回收,在特殊场合会有内存泄漏的风险。因此,如果延迟回收的问题比较重要,应该在外部类的生命周期结束之前要手动结束内部类的生命周期,否则可以直接交给虚拟机的GC机制解决。
虽然成员内部类可以自由访问外部类的成员变量和方法,但是外部类访问成员内部类的成员变量或者必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。
1.2 静态内部类
要注意的是,与静态方法和静态成员变量相同,在虚拟机启动的时候就被加载到内存中,而且此时还没有外部类的实例化对象。因此和静态方法一样,静态内部类不能访问任何外部类非静态的的成员变量和方法。并且,静态内部类不会持有外部类的引用,相比于成员内部类,没有内存泄漏的风险。
1.3 局部内部类
定义在外部类的方法中的内部类。
1.4 匿名内部类
2、访问权限
3、总结
根据上面的分析,可以总结出内部类的一些知识点:
参考资料
https://zhuanlan.zhihu.com/p/57859259
https://zhuanlan.zhihu.com/p/93660248