Java 静态常量类变量赋值



我正在用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 中定义的内存地址的指针一样。

最新更新