我正在用Java创建一个Vector2类,并遇到一个问题:
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0,0);
...
}
在另一堂课上,我想这样称呼 ZERO:
Vector2 myVector = Vector2.ZERO; //initialize to zero
myVector.add(myOtherVector); //myVector is now the sum of Vector2.ZERO and myOtherVector
然而,这行为是不可取的:myVector只是变成了Vector2.ZERO——因此是不可改变的——而不是被初始化为零值,然后可以随心所欲地使用。要获得我想要的行为,我需要:
Vector2 myVector = new Vector2(Vector2.Zero); //initialize to zero with copy constructor
我对这里的Java语义有点困惑(即someVector本质上似乎是一个指针而不是一个实际的对象,所以我必须创建一个新对象并显式复制值。在阅读了这篇文章之后,我知道在这个话题上有很多困惑。有没有一种简单的方法可以实现我正在寻找的语法,或者我应该坚持使用 2?如果没有,有没有办法阻止选项 1 中的分配?如果我在编译时不停止它,以后会给我一些难以捕获的错误。
编辑:Vector2不是不可变的。我想要的是 Vector2.ZERO 是一个常量值,我可以用于赋值,但随后会正常操作这些新变量。现在,如果我在多个地方执行该分配,那么所有这些都只是指向同一对象的指针(因为它是静态的,所以只会累积更改)。
例如,在 Unity 中使用矢量时,我会这样说:
Vector2 myFirstVector = Vector2.ZERO; //first vector, initialized to zero
...//do some stuff to change the value of myFirstVector, Vector2.ZERO unchanged
Vector2 mySecondVector = Vector2.ZERO; //second vector, also initialized to zero
...//do some stuff to mySecondVector
如果您希望向量是可变的,那么拥有一个包含零向量的静态字段不是一个好的选择(因为它以后可能会变异为其他东西。
您可以采用两种方法:
可变向量
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
不可变向量
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0, 0);
private final int x;
private final int y;
public Vector2(int x, int y) {
this.x = x;
this.y = y;
}
public Vector2 add(Vector2 v) {
return new Vector2(this.x + v.x, this.y +v.y);
}
}
您可能希望创建一个静态工厂方法来返回一个归零的新 Vector。
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
然后使用它:
Vector2 myVector = Vector2.Zero();
当然,如果你的默认构造函数将向量初始化为 0,0,那么你可能不需要这个,只需执行以下操作: Vector2 myVector = new Vector2();
你最初的想法:"但是,这行为不理想:myVector只是变成了Vector2.ZERO--因此不可更改---"是不正确的,除非Vector2是不可变的。 您将无法将任何其他内容重新分配给 Vector2.ZERO,但您当然可以修改对象的内容。
使你的类不可变,这样add()
就会返回一个新实例而不是修改实例,然后:
myInstance = myInstance.add(myOtherVector);
请参阅 BigInteger
中 JDK 中的工作方式如下的类。
这就是 OOP 和对象引用的重点。
Vector2 myVector = Vector2.ZERO;
表示您的myVector
变量将引用与静态字段相同的对象(在内存中Vector2.ZERO
。基本上,它是引用内存中的同一对象。
你写道:
someVector本质上似乎是一个指针
嗯,这就是前提。引用可以理解为指向对象的指针,就像指向 C 中定义的内存地址的指针一样。