Question

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
Was it helpful?

Solution

If you want your vectors to be mutable, having a static field that holds the zero vector is not a good choice (since it can mutate to something else later.

There are two approaches that you can take:
Mutable Vectors

public class Vector2 {
    public static Vector2 Zero() {
         return new Vector2(0,0);
    }
}

Immutable vectors

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);
  }
}

OTHER TIPS

You may want to create a static factory method to return a new Vector that is Zeroed.

public class Vector2 {
    public static Vector2 Zero() {
         return new Vector2(0,0);
    }
}

Then use it:

Vector2 myVector = Vector2.Zero();

Of course, if your default constructor initializes the vector to 0,0, then you may not need this and can simply do: Vector2 myVector = new Vector2();

Your initial thought about: "However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--" is incorrect unless Vector2 is immutable. You won't be able to reassign anything else to Vector2.ZERO, but you can certainly modify the object's contents.

Make your class immutable, so add() would return a new instance rather than modifying the instance, then:

myInstance = myInstance.add(myOtherVector);

See BigInteger for a class from the JDK that works like this.

That is the whole point of OOP and object references.

Vector2 myVector = Vector2.ZERO;

means that your myVector variable will reference to the same object (in memory) as static field Vector2.ZERO does. Basicly it is reffering the same object in memory.

You wrote:

someVector essentially seems to be a pointer

well, that is preatty it. References can be understood as pointers to objects just as pointers to defined memory address in C.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top