Java内部类持有外部类的引用详细分析与解决方案
来源:互联网 发布:淘宝商家数量统计 编辑:程序博客网 时间:2024/04/29 12:33
在Java中内部类的定义与使用一般为成员内部类与匿名内部类,他们的对象都会隐式持有外部类对象的引用,影响外部类对象的回收。
GC只会回收没有被引用或者根集不可到达的对象(取决于GC算法),内部类在生命周期内始终持有外部类的对象的引用,造成外部类的对象始终不满足GC的回收条件,反映在内存上就是内存泄露。(如,Android中Activity的内存泄露)
解决方案为
1.将内部类定义为static
2.用static的变量引用匿名内部类的实例或将匿名内部类的实例化操作放到外部类的静态方法中
测试代码
class Outer { class Inner { public String publicString = "Inner.publicString"; } Other anonymousOther = new Other() { public String publicString = "Anonymous Other.publicString"; }; public Other getAnonymousOther() { return anonymousOther; } Other Other = new Other(); public Other getOther() { return Other; }}class Other { public String publicString = "Other.publicString";}
调用代码
public static void main(String args[]) { printField(new Outer().new Inner()); System.out.println("\t"); printField(new Outer().getAnonymousOther()); System.out.println("\t"); printField(new Outer().getOther()); }
测试结果
Class: at.miao.Outer$Inner变量: publicString 值为 Inner.publicString变量: this$0 值为 at.miao.Outer@456c5f50Class: at.miao.Outer$1变量: publicString 值为 Anonymous Other.publicString变量: this$0 值为 at.miao.Outer@10e80317Class: at.miao.Other变量: publicString 值为 Other.publicString
可以看到内部类与匿名内部类的实例都有一个外部类类型的名为this$0的变量指向了外部类的对象。
加上static之后,代码为
class Outer { static class Inner { public String publicString = "Inner.publicString"; } static Other anonymousOther = new Other() { public String publicString = "Anonymous Other.publicString"; }; public Other getAnonymousOther() { return anonymousOther; } Other Other = new Other(); public Other getOther() { return Other; }}class Other { public String publicString = "Other.publicString";}
调用代码
public static void main(String args[]) { printField(new Outer.Inner()); System.out.println("\t"); printField(new Outer().getAnonymousOther()); System.out.println("\t"); printField(new Outer().getOther()); }
测试结果
Class: at.miao.Outer$Inner变量: publicString 值为 Inner.publicStringClass: at.miao.Outer$1变量: publicString 值为 Anonymous Other.publicStringClass: at.miao.Other变量: publicString 值为 Other.publicString
可以看到静态内部类实例、static引用的匿名内部类的实例未引用外部类的实例。
将匿名内部类的实例化操作放到外部类的静态方法中也可以达到上述效果:
public static Other getAnonymousOther() { return new Other() { public String publicString = "Anonymous Other.publicString"; }; }
调用代码
printField(Outer.getAnonymousOther());
采用静态化的方式不一定是最好的解决方案,请根据业务需要以及代码优化需要选择。
2 1
- Java内部类持有外部类的引用详细分析与解决方案
- Android非匿名内部类持有外部类的引用
- Java中非静态内部类对象持有外部类对象的引用。
- 匿名内部类的demo演示(匿名内部类持有外部类的实例引用)
- 非静态的内部类会持有外部类的一个隐式引用
- 非静态的内部类会持有外部类的一个隐式引用
- 非静态内部类为什么持有外部类的this引用
- 非静态内部类持有外部类的引用 使用不慎会造成内存溢出
- 非静态内部类、非静态匿名内部类会持有外部对象的引用
- java awt 持有对方引用、内部类
- 非静态的内部类会持有外部类的一个隐式引用 造成内存泄露
- java 非静态内部类与外部类引用之间的关系
- Java内部类与外部类
- java 内部类与外部类学习
- java外部类与内部类的关系
- java外部类与内部类的关系
- java中内部类与外部类的区别
- 【Java】内部类与外部类的互访使用小结
- JVM守护线程和非守护线程
- SQL的四种连接-左外连接、右外连接、内连接、全连接
- 菜鸟之路——Spring MVC(八)静态资源
- 详解CSS中flex布局
- mybatis 读取blob数据
- Java内部类持有外部类的引用详细分析与解决方案
- 第十周-回文数
- 11.6 java中jar包使用
- [转] thttpd服务器在时间修改后导致CPU占用率过高的问题
- I2C设备地址查询
- Linux Mint电池供电时鼠标间歇失灵
- USACO 2004 Mar 赞助学费 finance 堆
- 8种常见的排序算法
- 想、做和实现