2

I'm creating a Vector2 class in Java, and have an issue:

public class Vector2 {
    public static final Vector2 ZERO = new Vector2(0,0);
    ...
}

in another class, I'd like to call ZERO like this:

Vector2 myVector = Vector2.ZERO; //initialize to zero
myVector.add(myOtherVector); //myVector is now the sum of Vector2.ZERO and myOtherVector

However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--rather than being initialized to the zero value and then being free to work with as I wish. To get the behavior I want, I need:

Vector2 myVector = new Vector2(Vector2.Zero); //initialize to zero with copy constructor

I'm a little confused by Java's semantics here (i.e someVector essentially seems to be a pointer rather than an actual object, so I have to create a new object and explicity copy the values.) After reading up on that, I understand there's a lot of confusion on that topic. Is there a simple way to achieve the syntax I'm looking for or should I just stick with option 2? If there isn't, is there a way to prevent the assignment in option 1? It's going to give me some hard to catch errors later if I don't stop it at compile time.

Edit: Vector2 isn't immutable. What I'd like is for Vector2.ZERO to be a constant value I can use for assignments, but then manipulate those new variables normally. Right now if I do that assignment in multiple places, then all of those are just pointers to the same object (which because it's static just accumulates the changes).

For example, in Unity when working with vectors I would say something like:

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
4

4 回答 4

3

如果你希望你的向量是可变的,拥有一个包含零向量的静态字段不是一个好的选择(因为它可以在以后变异为其他东西。

您可以采用两种方法:
可变向量

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);
  }
}
于 2013-11-05T12:36:06.240 回答
2

您可能想要创建一个静态工厂方法来返回一个已归零的新向量。

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,但您当然可以修改对象的内容。

于 2013-11-05T12:33:07.623 回答
1

使您的类immutable,因此add()将返回一个新实例而不是修改该实例,然后:

myInstance = myInstance.add(myOtherVector);

请参阅BigIntegerJDK 中的一个像这样工作的类。

于 2013-11-05T12:40:14.887 回答
0

这就是 OOP 和对象引用的重点。

Vector2 myVector = Vector2.ZERO;

意味着您的myVector变量将引用与静态字段相同的对象(在内存中)Vector2.ZERO。基本上它是在内存中引用相同的对象。

你写了:

someVector 本质上似乎是一个指针

嗯,就是这样。引用可以理解为指向对象的指针,就像指向 C 中定义的内存地址的指针一样。

于 2013-11-05T12:31:46.063 回答