【问题标题】:Object References Java对象引用 Java
【发布时间】:2014-05-03 17:17:10
【问题描述】:

我有这个对象引用的问题,这让我发疯。当我从对象中获取 Integer[] 数组并修改此变量中的某些元素时,它在对象中也被修改而不使用任何 set 方法是否正常?例如下面我想在本地修改时间表变量,而不是在 bestSoFar 对象中。我怎样才能做到这一点?这里到底发生了什么?

for (IntTuple examRel: examsRel) 
{   
     int[] examsTogether = examRel.getData();
     double maxFitness = 0.0;
     Integer[] timetable = bestSoFar.getChromosome();

     for (int i=0; i < noOfTimeslots; i++)
     { 
          for (int j=0; j < examsTogether.length; j++)
          {
               timetable[examsTogether[j]] = i;
          }

          BestChromosome thisChromosome = evaluateChromosome(new BestChromosome(timetable));
          double thisFitness = thisChromosome.getFitness();

          if (thisFitness > maxFitness)
          {
              maxFitness = thisFitness;
              bestSoFar = thisChromosome;
          }
       }
    }
    return bestSoFar;
}

【问题讨论】:

  • 显然getChromosome() 正在返回对底层存储的引用,而不是先创建副本。
  • 是的,这很正常,因为你得到了Integer[]数组的引用。如果您需要其他行为,则应考虑在返回之前克隆数组。
  • 一个数组是一个普通的对象。你有它的参考,你可以改变它的成员。您必须创建它的副本。你可以使用 Arrays.copyOf (docs.oracle.com/javase/7/docs/api/java/util/…)
  • 所以我需要将数组复制到另一个 Integer[] 数组中?

标签: java arrays object reference


【解决方案1】:

Java 中的数组是一个对象,因此当您修改它的元素时,它们会随着指向该数组的所有引用而改变。 如果你想要一个本地副本,你应该克隆它。例如:

Integer[] origTimetable = bestSoFar.getChromosome();
Integer[] timetable = Arrays.copyOf (origTimetable, origTimeable.length);

【讨论】:

  • 感谢您的回答。因此,如果我有此时间表的副本并对其进行修改,则不会修改染色体中的时间表。但是如果数组是原始的 int[] 会避免这种情况吗?
  • @Bernice 不,使用原始 ints 无济于事 - 这里的对象引用是数组本身 - 您的代码没有修改现有元素,而是用不同的元素切换它们。原始数组ints 也会出现完全相同的问题。
  • 好的,BestChromosome 的对象也是如此。我在哪里做得最好SoFat = thisChromosome 我会通过对两个对象使用相同的引用来使它们相等,对吗?
  • @Bernice 是的。两个变量都指向同一个引用。
【解决方案2】:

是的,这很正常。该方法返回对包含在对象中的数组的引用。如果你改变了数组包含的内容,那么数组就会被修改。

您必须在返回数组之前制作一个防御性副本。

您可以改用List&lt;Integer&gt; 来避免这些副本,并返回此列表的不可修改视图以防止对其进行修改。如果需要修改它,则由调用者创建列表的副本:

return Collections.unmodifiableList(list);

【讨论】:

    猜你喜欢
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    相关资源
    最近更新 更多