Problem with passing around Object references in Java
i'm writing some stuff in java and i ran into some problems lately. cut short, i need to compare an object i created to another instance of this very class i instantiazed before with different data.
looks like this:
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;
}
with a class a:
class a {
public long time;
public int x;
public a() {
time = System.currentTimeMillis;
}
}
the problem is, that i end up finding out that the values from newA are always equal to those from oldA. so i guess sth w开发者_Go百科ent wrong with passing the references of the objects in the last line of the loop... i thought java always passes references of objects unless an explicit copy() is called?
if this does matter: this code is running on android - don't know if the dalvik vm messes aroung with this...
I'm thinking you probably do have two different objects, but they both have the same value for time
. Current millis doesn't quite have the precision to distinguish between two objects constructed in rapid succession, unless if your inner loop is long running. Even a Mhz processor will have iterations measured in microseconds, not milliseconds.
There is a chance, that two a
objects are created within the same millisecond, so there 'time' fields are equal.
I'm not sure about you comparision requirements, but maybe you should overwrite 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);
}
}
then just do a
if (!(newA.equals(oldA)) {
// ...
}
For future coding - please name classes so that they start with an upper case letter (coding conventions)
By "I end up with", do you mean "after I get out of the while
loop"?
Because in that case, then the problem is simple: in the last loop iteration, oldA is overwritten with the last value of newA, while newA is never overwritten with a new instance of a.
So, when you get out of the while
loop, newA and oldA are always equal - the consequence of the last attribution step of the last loop execution.
I don't know how to put code into comments so I'll add this as a response to Aymen's answer which is wrong :)
Try this and you'll see exactly what's going on :)
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());
}
}
In the last line of your loop you write oldA=newA
this makes oldA and newA share the same reference. So, when you change the value of newA with newA=new a()
, the value of oldA changes too (so you will have oldA.x==newA.x).
Edit: I've made some tests and i discovered that what I said was totally wrong, sorry about that. However, the code given by xenonite works fine. The condition newA.time != oldA.time
is satisfied.
精彩评论