ArrayList.clear()是否以递归方式使所有对象无效?

时间:2014-07-13 11:32:14

标签: java arraylist

我们说我有这样一个班级:

class C
{
   int a, b;
   ArrayList<int> c = new ArrayList();
};

和这样的集合:

ArrayList<ArrayList<C>> MyList = new ArrayList<ArrayList<C>>();

调用MyList.clear()会取消对MyList中每个ArrayList的所有引用以及MyList中每个ArrayList内的任何其他对象吗?因此,更准确地说,C类中的所有元素都将被取消,以及C.a和C.b?

2 个答案:

答案 0 :(得分:6)

不,但如果没有其他内容可以引用它们,那么 将有资格进行垃圾回收。

,例如,更简单的例子:

class Foo {
    Date dt;

    Foo() {
        this.dt = new Date();
    }
}

ArrayList<Foo> list = new ArrayList<Foo>();
list.add(new Foo());
list.clear();

截至clearFoo对象的dt尚未被“删除”或任何内容,但Foo对象及其引用的内容(其中Date,在这种情况下)有资格进行垃圾收集。

鉴于:

class Foo {
    Date dt;

    Foo() {
        dt = new Date();
    }
}

ArrayList<Foo> list = new ArrayList<Foo>();
Foo f = new Foo();
list.add(f);
list.clear();

此处,Foo对象不符合条件进行垃圾回收,因为即使列表没有,f仍然引用它。当然,如果f是方法中的局部变量,那么只要方法返回,f就会超出范围 - 此时,如果没有其他任何东西对该对象有引用,那么有资格获得GC。但是,除此之外,关键是当clear完成时,仍然会引用该对象(f)。

答案 1 :(得分:3)

如果c是唯一包含对包含列表的强引用的对象,那么最终它们将被垃圾收集。

它们不会直接清空,只是从包含列表中删除。例如

ArrayList<C> inner = new ArrayList<C>();
inner.add(new C());

ArrayList<ArrayList<C>> outer = new ArrayList<ArrayList<C>();
ArrayList<ArrayList<C>> outer2 = new ArrayList<ArrayList<C>();

outer.add(inner);
outer2.add(inner);

outer.clear();

在这种情况下,inner将从outer移除,但不会从inner2移除,并且由于会有另一个强引用inner,因此不符合垃圾回收条件。否则它将被平衡释放,但不是一次性释放,而不是清空内部元素。