内部类是Java语言中一个被广泛使用的特性,但是,有时候使用不注意可能会引起一些资源回收的问题,请看下面的代码:
public class JavaLeakTest { static List<Element> sList = new ArrayList<Element>(); Element mData; public JavaLeakTest() { mData = new Element(); } class Element{ } static void addElement(){ JavaLeakTest obj = new JavaLeakTest(); sList.add(obj.mData); } }
可以看到,这段代码里的addElement方法每次都往sList中加入一个新的Element对象,Element是JavaLeakTest的内部类,
然后问题来了:在执行完addElement以后,JavaListTest obj所指向的对象会被销毁吗?
答案是否定的,因为被add到sList中的Element对象obj.mData实际上隐式地拥有一个对外部对象obj引用,只要sList依然保持对obj.mData的引用,obj就不会被回收!
但是如果Element是这样定义的话:
static class Element{ }
问题就不会出现
这种定义意味着Element对象中不保留对JavaLeakTest对象的引用,这将失去一些功能(例如在Element中直接访问JavaLeakTest的非静态成员)。
所以,我们在使用内部类的时候,需要考虑到隐式引用引起的资源回收问题,同时需要结合需求进行取舍。