简体   繁体   English

Java增强型循环:引用集合未更改

[英]Java Enhanced For-Loop: Referenced Collection Not Changed

Something strange is going on, suppose I have this code with 'Attachment' objects, and I want to set all the objects to NULL. 发生了一件奇怪的事情,假设我的代码带有“附件”对象,并且我想将所有对象设置为NULL。

List<Attachment> attachments = getAttachments();

for (Attachment attachment: attachments)
{
   attachment = null;
}

The immediate object attachment is successfully set to NULL. 立即对象附件已成功设置为NULL。 But the backing collection is untouched. 但是支持集合没有被改变。 It still has the old data. 它仍然具有旧数据。 I thought we could always rely on references in Java? 我以为我们总是可以依靠Java中的引用?

Yes, you can rely on references in Java, if you understand them correctly. 是的,如果您正确理解了引用,则可以依靠Java中的引用。 You have a reference variable attachment , but it is one of 2 references referring to the object you want to set to null . 您有一个引用变量attachment ,但这是2个引用的引用之一,引用要设置为null的对象。

attachments -> { Attachment, Attachment, Attachment }
                     |           |           |
                     v           v           v
  attachment -->  (object)    (object)    (object)

When you assign null to attachment , the list reference isn't changed. 当为attachment分配null时,列表引用不会更改。

attachments -> { Attachment, Attachment, Attachment }
                     |           |           |
                     v           v           v
  attachment      (object)    (object)    (object)
      |
      v
    (null)

An enhanced for loop won't let you change the list contents this way. 增强的for循环不会让您以这种方式更改列表内容。

You can use a traditional for loop, and call set : 您可以使用传统的for循环,并调用set

for (int i = 0; i < attachments.size; i++)
{
    attachments.set(i, null);
}

BTW, it's unclear why you want to set all elements to null . 顺便说一句,尚不清楚为什么要将所有元素都设置为null This leaves n copies of null in the list. 这将在列表中保留nnull副本。 An alternative is to remove all references to the list with attachments.clear() , which will leave no references at all in the list, not even null , in case that's what you really want to do. 另一种方法是用删除所有引用到列表attachments.clear()这将不留在引用列表中的所有,甚至不null ,如果这就是你真正想做的事情。

You can't modify the contents of a Collection when traversing it in an enhanced for loop. 在增强的for循环中遍历Collection的内容时,您无法对其进行修改。

The attachment object that you get on every iteration is like a copy (it's actually just another reference to that object) of the object in the collection, so basically you are assigning null to that 'temporary' object, not to the actual element inside the collection. 您在每次迭代中获得的attachment对象就像集合中对象的副本(实际上只是对该对象的另一个引用),因此,基本上,您是将null分配给该“临时”对象,而不是分配给对象中的实际元素采集。

The assignment of null to your attachment variable can not alter the collection because attachment is a reference to an Attachment object, not the collection itself. 将null分配给附件变量不能更改集合,因为附件是对附件对象的引用,而不是对集合本身的引用。

Your attachments collection contains references to Attachment objects. 您的附件集合包含对附件对象的引用。 Each iteration of the loop, Java assigns the next object reference in the collection to your attachment variable. 循环的每次迭代,Java都会将集合中的下一个对象引用分配给您的附件变量。 If you subsequently change your attachment variable, that can not alter the collection itself. 如果随后更改了附件变量,则不能更改集合本身。

The identifier in the header of the enhanced for statement declares a local variable , as stated in the Java Language Specification . 增强的for语句的标头中的标识符声明了一个局部变量 ,如Java语言规范中所述 In your case, attachment is a local variable. 在您的情况下, attachment是局部变量。 When you set it to null , it won't impact the object it is pointing to. 将其设置为null ,它不会影响它指向的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM