在java中清除或设置空对象 [英] clearing or set null to objects in java

查看:30
本文介绍了在java中清除或设置空对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在研究释放 Java 对象占用的内存.这样做时,我对 Java 中如何复制对象(浅/深)以及如何避免在对象仍在使用时意外清除/无效感到困惑.

I was recently looking into freeing up memory occupied by Java objects. While doing that I got confused about how objects are copied (shallow/deep) in Java and how to avoid accidently clearing/nullifying objects while they are still in use.

考虑以下场景:

  1. ArrayList 作为参数传递给方法.
  2. ArrayList 传递给线程处理的可运行类.
  3. ArrayList 放入 HashMap.
    1. passing a ArrayList<Object> as an argument to a method.
    2. passing a ArrayList<Object> to a runnable class to be processed by a thread.
    3. putting a ArrayList<Object> into a HashMap.

    现在在这些情况下,如果我调用 list = null;list.clear();,对象会发生什么变化?在哪种情况下对象会丢失,在哪种情况下仅将引用设置为空?

    Now in these case, if I call list = null; or list.clear();, what happens to the objects? In which case the objects are lost and in which cases only the reference is set to null?

    我猜这与对象的浅拷贝和深拷贝有关,但是在哪些情况下会发生浅拷贝,在哪些情况下会发生深拷贝?

    I guess it has to do with shallow and deep copying of objects, but in which cases does shallow copying happens and in which case does deep copy happens in Java?

    推荐答案

    首先,您永远不要将 object 设置为 null.这个概念没有意义.你可以给一个变量赋值null,但是你需要非常仔细地区分变量"和对象"的概念.一旦你这样做了,你的问题就会自己回答:)

    Firstly, you never set an object to null. That concept has no meaning. You can assign a value of null to a variable, but you need to distinguish between the concepts of "variable" and "object" very carefully. Once you do, your question will sort of answer itself :)

    现在就浅拷贝"与深拷贝"而言——这里可能值得避免使用浅拷贝"一词,因为通常浅拷贝涉及创建一个新对象,但只是直接复制现有对象的字段.深拷贝也会复制这些字段所引用的对象(对于引用类型字段).像这样的简单分配:

    Now in terms of "shallow copy" vs "deep copy" - it's probably worth avoiding the term "shallow copy" here, as usually a shallow copy involves creating a new object, but just copying the fields of an existing object directly. A deep copy would take a copy of the objects referred to by those fields as well (for reference type fields). A simple assignment like this:

    ArrayList<String> list1 = new ArrayList<String>();
    ArrayList<String> list2 = list1;
    

    ... 不做 那种意义上的浅拷贝或深拷贝.它只是复制引用.在上面的代码之后,list1list2 是独立变量——它们恰好具有相同的值(引用).我们可以更改其中一个的值,而不会影响另一个:

    ... doesn't do either a shallow copy or a deep copy in that sense. It just copies the reference. After the code above, list1 and list2 are independent variables - they just happen to have the same values (references) at the moment. We could change the value of one of them, and it wouldn't affect the other:

    list1 = null;
    System.out.println(list2.size()); // Just prints 0
    

    现在,如果我们不更改变量,而是更改变量值所引用的对象,那么该更改也将通过另一个变量可见:

    Now if instead of changing the variables, we make a change to the object that the variables' values refer to, that change will be visible via the other variable too:

    list2.add("Foo");
    System.out.println(list1.get(0)); // Prints Foo
    

    回到你最初的问题——你永远不会在地图、列表、数组等中存储实际对象.你只存储引用.只有当活动"代码无法再到达该对象时,该对象才能被垃圾回收.所以在这种情况下:

    So back to your original question - you never store actual objects in a map, list, array etc. You only ever store references. An object can only be garbage collected when there are no ways of "live" code reaching that object any more. So in this case:

    List<String> list = new ArrayList<String>();
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    map.put("Foo", list);
    list = null;
    

    ... ArrayList 对象仍然不能被垃圾回收,因为 Map 有一个引用它的条目.

    ... the ArrayList object still can't be garbage collected, because the Map has an entry which refers to it.

    这篇关于在java中清除或设置空对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆