有关Java中对象相等性的一般信息

时间:2014-09-18 10:00:07

标签: java

我目前正在学习Java游戏开发,并且正在尝试使用向量/点而不是基元来定位实体。在整个实验过程中,我发现了一些关于物体工作的方法,我不知道如何解决这些问题,请考虑这个例子。

Point p1 = new Point(0, 0);
Point p2 = p1;

p1.x++;

if (p1 == p2) System.out.println("these are the same");

更改了p1的坐标后,仍然处理了println,经过调试后我通过设置p2 = p1计算出p1发生的任何变化都将发送到p2。

最终我想知道为什么会这样。对象名称是否只是指向内存中某个位置的指针,这两个点都指向一个位置?

此外,还有办法吗?

6 个答案:

答案 0 :(得分:1)

  

..对象名称是否只是指向内存中某个位置的指针,这两个点都指向一个位置?

是。真正。我们在Java中将其称为 reference p2指的是p1。由于p2不是new对象且总是指向p1,因此您对p1所做的更改也可以通过p2查看。< / p>

图片可以解释更多。

enter image description here

**以上图片版权属于此blog

答案 1 :(得分:1)

正如你所说:

Are the object names just a pointer to a location in memory 
and both of these Points are pointing to one location?

用C语言,这将是这样的:

Point* p1 = (Point*)malloc(sizeof(Point));
Point* p2 = p1;

解决方案当然是在两个指针上有两个不同的对象:

Point* p1 = (Point*)malloc(sizeof(Point));
Point* p2 = (Point*)malloc(sizeof(Point));

或者像在Java中一样:

Point p1 = new Point(0, 0);
Point p2 = new Point(0, 0);

或者也许只是初始化第二个:

Point p2 = new Point(p1.getX(), p1.getY());

值得注意的是,对于Objects,在Java中,==运算符是引用相等,又名“这指向同一个对象”。如果要根据内容比较两个对象,则应覆盖.equals()方法。大多数IDE可以根据给定类中的属性自动生成它。

答案 2 :(得分:0)

正如您已经猜到的那样,Java对象变量只是引用(指向内存的指针),因此编写

Foo a = new Foo();
Foo b = a;

只会创建一个 Foo - 对象,现在由两个变量ab引用。更改引用的对象b也会更改引用的对象a,因为它们引用同一个对象。

将两个引用与== - 运算符进行比较将检查它们是否引用完全相同的对象。如果要根据值对两个对象进行比较,请使用equals() - 方法:

Foo a = new Foo();
Foo b = new Foo();

if(a.equals(b))
  System.out.println("It seems that Foo() generates Foos with the same values everytime");

使用.clone()可以克隆一个对象,但是要小心它 - 它只会默认复制具有所有值的对象 - 不会调用构造函数,这会导致难以跟踪的错误调用构造函数很重要。我不建议在对象上使用.clone()而不知道对他们的类进行安全。您始终可以实施自己的clone() - 强烈推荐的方法。

答案 3 :(得分:0)

你是对的,虽然在Java中没有像指针那样的东西。两个变量(p1和p2)都是引用到内存中的同一个对象。

所以在你的情况下你可能想要这样的东西:

Point p1 = new Point(0, 0);
Point p2 = new Point(p1);

什么是非常重要: 比较两个对象时不要使用==运算符 - 而是使用.equals()

if (p1.equals(p2)) System.out.println("these are the same");

答案 4 :(得分:0)

Java(Object)的基类具有clone和equals方法,因此它是基本Java系统的一部分。但是,如果您阅读Object类的文档,它会对这些方法的作用有一些警告。我会使用以下内容并确保您对其进行测试以确保您获得所需的行为。

Point p1 = new Point(0, 0);
Point p2 = p1.clone();


if (p1.equals(p2)) System.out.println("these are the same");

答案 5 :(得分:0)

物体和记忆。

enter image description here

我希望很清楚图片中显示的是什么。最后@BBB和@CCC地址单元将是垃圾收集器的工作(因为它们现在都没有引用真实对象)。

我们可能会做一个测试,以显示真实物体的发生情况。

让我们创建简单的类。

class A {
    private int value;

    public A(int value) {
        this.value = value;
    }

    public void increase() {
        this.value++;
    }

    public int getValue() {
        return value;
    }
}

用于查看对象的内存链接如何更改的简单用法:

package test;

public class Starter {

    public static void main(String[] args) {
        A a = new A(1);
        A b = new A(4);
        A c = new A(7);

        System.out.println("a.value= " + a.getValue());
        System.out.println("b.value=" + b.getValue());
        System.out.println("c.value=" + c.getValue());
        System.out.println("\nMemory cells address: ");
        System.out.println("a : " + a);
        System.out.println("b : " + b);
        System.out.println("c : " + c);

        System.out.println("\nAfter b = a;");
        b = a;
        System.out.println("\nb : " + b);

        System.out.println("\nAfter c = b;");
        c = b;
        System.out.println("c : " + c);

        System.out.println("\nAfter a.increase(); All values of all objects will be same, because all of them are linked to one same memory address.");
        a.increase();
        System.out.println("a.value=" + a.getValue());
        System.out.println("b.value=" + b.getValue());
        System.out.println("c.value=" + c.getValue());

        System.out.println("\nAfter c.increase(); All values of all objects will be same, because all of them are linked to one same memory address.");
        a.increase();
        System.out.println("a.value=" + a.getValue());
        System.out.println("b.value=" + b.getValue());
        System.out.println("c.value=" + c.getValue());
    }

}

运行示例后,请注意对象引用(地址)

就我而言,我收到的内容如下:

a.value= 1
b.value=4
c.value=7

Memory cells address: 
a : test.A@6d4b2819
b : test.A@6135b95d
c : test.A@e1cba87

After b = a;

b : test.A@6d4b2819

After c = b;
c : test.A@6d4b2819

After a.increase(); All values of all objects will be same, because all of them are linked to one same memory address.
a.value= 2
b.value=2
c.value=2

After c.increase(); All values of all objects will be same, because all of them are linked to one same memory address.
a.value=3
b.value=3
c.value=3