在Java中传递Object引用的问题

时间:2010-06-25 07:54:13

标签: java android object copy reference

我正在用java写一些东西,最近我遇到了一些问题。简而言之,我需要将我创建的对象与之前使用不同数据实例化的这个类的另一个实例进行比较。

看起来像这样:

a newA = null;
a oldA = null;

while(someBreakCondition) {
    newA = new a();

    newA.x = getSomeValue();

    // now i want to compare the two objects
    if(oldA != null) {
        if(newA.time != oldA.time) {
            // ...
        }
    }

    // now my newA gets to be my oldA, since in the next iteration, a new newA is created
    oldA = newA;
}

有一个班级:

class a {
    public long time;
    public int x;

    public a() {
        time = System.currentTimeMillis;
    }
}

问题是,我最终发现newA的值总是等于oldA的值。所以我猜测在循环的最后一行传递对象的引用是错误的... 我认为除非调用显式的copy(),否则java总是传递对象的引用?

如果这很重要:这个代码在android上运行 - 不知道dalvik vm是否因为这个问题而混乱......

5 个答案:

答案 0 :(得分:7)

我想你可能确实有两个不同的对象,但它们对time都有相同的值。除非你的内循环长时间运行,否则当前millis不能完全区分快速连续构造的两个对象。即使是Mhz处理器也会以微秒为单位进行迭代,而不是毫秒。

答案 1 :(得分:4)

有可能在同一毫秒内创建两个a个对象,因此“时间”字段相等。

我不确定你的比较要求,但也许你应该覆盖equals

public class A {
  private long time;
  private int x;

  public A() {
    time = System.currentTimeInMillis();
  }

  public void setX(int x) {
    this.x = x;
  }

  public int getX() {
    return x;
  }


  public boolean equals(Object other) {
    if (!(other instanceof A)) return false;

    // two A instances are equal if they are created 
    // within the same millisecond
    return ((A) other).time == time);
  }
}

然后只做一个

if (!(newA.equals(oldA)) {
  // ...
}

对于将来的编码 - 请命名类,使它们以大写字母(编码约定)开头

答案 2 :(得分:1)

我不知道如何将代码放入评论中,所以我会将此作为对Aymen答案的回应添加,这是错误的:)

试试这个,你会看到到底发生了什么:)

public class Test {
  private int value;
  public Test(){

  }

  public int getValue() {
    return value;
  }

  public void setValue(int value) {
    this.value = value;
  }


}

public class Main {

    public static void main(String[] args) {
      Test oldA = null;
      Test newA = null;


      newA = new Test();
      newA.setValue(1);

      oldA = newA;

      // both variables references the same object: output: 1 - 1
      System.out.println("newA: " + newA.getValue());
      System.out.println("oldA: " + oldA.getValue());

      newA = new Test();
      newA.setValue(2);

      // now we have different objects: output: 2 - 1
      System.out.println("newA: " + newA.getValue());
      System.out.println("oldA: " + oldA.getValue());

    }

}

答案 3 :(得分:1)

通过“我最终得到”,你的意思是“在我离开while循环后”吗?

因为在这种情况下,问题很简单:在最后一次循环迭代中,oldA被newA的最后一个值覆盖,而newA永远不会被a的新实例覆盖。

因此,当你离开while循环时,newA和oldA总是相等的 - 上一次循环执行的最后归因步骤的结果。

答案 4 :(得分:0)

在你的循环的最后一行写下oldA=newA 这使得oldA和newA共享相同的引用。因此,当您使用newA=new a()更改newA的值时,oldA的值也会更改(因此您将拥有oldA.x == newA.x)。

编辑:我做了一些测试,我发现我说的完全错了,对不起。但是,xenonite给出的代码工作正常。满足条件newA.time != oldA.time