Java内部类有静态内部类、非静态内部类和匿名内部类,需要明确的是所有的内部类都会被编译成和外部类一样的顶级类。
静态内部类/非静态内部类
静态内部类和非静态内部类的区别就是非静态内部类持有外部类的引用。编译期间会自动合成this$0表示外部类引用。
非静态内部类和外部类互相访问
:
在使用非静态内部类时,我们都知道外部类可以访问内部类的私有成员变量,反之亦然。
上面已经说过,内部同样会编译成顶级类,那他们是怎么实现互相访问私有成员的呢?
实际上为了让外部类可以访问内部类的私有成员或方法,编译器会为内部类自动生成 access&**
方法, access&**
会简单的返回内部类的私有成员或方法。反之同理。
热修复部署影响
由于访问内部类或外部类的私有成员或方法时,编译器会自动添加access&**
方法。所以当补丁类访问内部类或外部类的私有成员或方法时会导致方法数增加,进而引起热修复异常。
因此我们要避免内部类或外部类生成access&**
方法。
- 一个外部类如果有内部类,把外部类的所有method、field的private权限修改为protected或者默认权限或者public。
- 同时把内部类的所有method、field的private权限修改为protected或者默认权限或者public。
匿名内部类
匿名内部类是没有名字的,在编译成顶级类时的命名规则是外部类&number,number是根据匿名类的出现顺序命名的。
匿名内部热修复部署影响
由于匿名内部类的特殊命名规则,当补丁类在之前的匿名内部类之前再插入一个匿名内部类的话,会导致编译后的匿名内部类和之前的对应关系出现了混乱。
因此,避免插入新的匿名内部类或删除,当然匿名内部类是插入到外部类的末尾,那是允许的。