【问题标题】:HashMap not modifiying object contentsHashMap 不修改对象内容
【发布时间】:2013-10-25 14:25:10
【问题描述】:

我有一个哈希图,我在其中引用了一个对象。

     DateTest test100 = new DateTest("ABC",100); 
     dateTestMap.put(96, test100);

我将此引用变量传递给一个方法,在该方法中我为其分配一个不同的对象,返回后我将现有引用指向新对象,如下所示:

    test100 = datePassingTest(test100);

    private DateTest datePassingTest(DateTest test100)
    {
        DateTest newTest = new DateTest("XYZ", 69);
        test100 = newTest;
        return test100;
    }

好吧,test100 确实被修改为指向新对象,但存储在 map 中的值没有得到更新。我有什么遗漏吗?

谢谢, 阿迪提亚

【问题讨论】:

    标签: java pass-by-value


    【解决方案1】:

    这是因为test100 没有持有使用此new DateTest("ABC",100); 创建的对象的引用。它现在指向由 new DateTest("XYZ", 69); 创建的对象。

    如果您做了类似test100.setSomething(150) 的操作,那么更改将反映在地图中。在这种情况下,它不会因为 test100 现在引用一个完全不同的对象。

    【讨论】:

    • 您的意思是地图内的 test100 引用和 test100 引用是 2 个不同的副本,即我的意思是这两个副本指向 test100 对象吗?并且在该方法仅返回参考 test100 (不是地图参考)之后指向新对象?这是否意味着 java 在将值存储在映射中时会复制引用 test100 ?
    • 它只存储参考。不是对象或其他东西的副本。看看this answer。它清楚地解释了一切。
    【解决方案2】:
    DateTest test100 = new DateTest("ABC",100); 
    dateTestMap.put(96, test100);
    

    这里有一个参考副本test100)进入指向DateTest("ABC",100)dateTestMap。现在,HashMap dateTestMap 包含一个 新引用,它指向 相同的对象 DateTest("ABC",100)

    所以它可以被描绘成这样

    当你这样做时

    test100 = datePassingTest(test100);
    

    外部test100 将指向new DateTest("XYZ", 69),但dateTestMap 中的复制引用 仍然指向同一个DateTest("ABC",100) 对象。

    Java 是按值传递 - 这实质上意味着传递引用的副本

    【讨论】:

    • 地图中的外部 test100 和 test100 引用是相同的,所以如果外部 test100 指向一个新对象,则地图引用理想情况下应该指向同一个新对象,除非地图制作另一个副本引用并存储引用!
    • 当我说 reference 被复制 时,我很清楚内部和外部 test100 不一样。
    【解决方案3】:

    当你这样做时

    test100 = newTest
    

    唯一要做的是 test100 现在引用与 newTest 相同的对象。 test100 的原始值所引用的对象仍然存在,但只存在于 hashmap 中。

    要做你想做的事,你应该尝试

    test100.setTime(newTest.getTime());
    

    【讨论】:

      【解决方案4】:

      那是因为,您将对象放在地图中,然后修改对象。因此,地图仍会保留旧对象

       DateTest test100 = new DateTest("ABC",100); 
       dateTestMap.put(96, test100);           // entry/object added to map
      
       test100 = datePassingTest(test100);     // object updated
      
       dateTestMap.put(96, test100);           // map gets new object
      
      // now the map contains the updated object but not the older one.
      

      【讨论】:

        【解决方案5】:

        您没有修改object。你只是assigning

        Language Specification JLS#4.301中解释清楚,

        如果两个变量包含对同一个对象的引用,则可以使用一个变量对该对象的引用来修改对象的状态,然后可以通过另一个变量中的引用来观察改变的状态。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-28
          • 1970-01-01
          • 2015-09-16
          • 2011-10-22
          • 2013-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多