让java等待直到调用属性?

让java等待直到调用属性?,java,stack-overflow,jogl,Java,Stack Overflow,Jogl,我最近开始与JOGL合作,所以我制作了一个向量类。在这个班里,我用了这句话 public Vector unit=new Vector(x/length,y/length,z/length); 求单位向量。当然,这会导致堆栈溢出。有没有办法让java在运行这个程序之前等待调用unit,或者我必须让unit成为一个方法?是的,这很简单,但您需要稍微修改一下设计。最重要的是,与所有成员变量的情况一样,unit应该是私有的,所有对它的访问都应该通过一个名为getUnit()的方法。然后,只需

我最近开始与JOGL合作,所以我制作了一个向量类。在这个班里,我用了这句话

    public Vector unit=new Vector(x/length,y/length,z/length);

求单位向量。当然,这会导致堆栈溢出。有没有办法让java在运行这个程序之前等待调用unit,或者我必须让unit成为一个方法?

是的,这很简单,但您需要稍微修改一下设计。最重要的是,与所有成员变量的情况一样,
unit
应该是私有的,所有对它的访问都应该通过一个名为
getUnit()
的方法。然后,只需编写
getUnit()
检查
unit
是否已初始化:

public synchronized Vector getUnit() {
    if (unit == null)
        unit = new Vector(x/length,y/length,z/length);
    return unit;
}

我将此方法
同步化
,这样,如果两个不同的线程几乎同时调用
getUnit()
,并且
unit
尚未初始化,您将避免任何问题。

我将亲自创建第二个构造函数,它计算单位向量并将自己的单位向量设置为自身。正如欧内斯特所建议的那样,您最好使用私有值和get方法。这样做的原因是,如果其他类可以访问您的某个对象,则它们可以简单地覆盖x、y、z等值。Java有使用最终类进行纯数据存储的传统。例如,请参见
字符串
类。您不能修改现有的
字符串
,只能创建新的
字符串
。创建后,
字符串保持不变。出于您的目的,这可能无关紧要,但在不同的上下文中,如果您的类被一个毫无线索的人使用,它可能会导致您的应用程序出现错误行为。在某些情况下,这甚至可能是一种安全风险

您可以简单地忽略这一点,直接访问变量,享受更少混乱的代码和较小的性能提升。但我还是建议你知道未来的问题是什么

无论如何,下面是我建议的解决单位向量问题的代码,减去getter方法

import java.lang.Math;

class Vector{
    public double x,y,z,length;
    public Vector unit;

    public static void main(String[]s){
        new Vector(5,5,5);

    }

    public Vector(double x, double y, double z){
        this.length = Math.sqrt(x*x + y*y + z*z);

        this.x=x;
        this.y=y;
        this.z=z;

        this.unit = new Vector(x/length, y/length, z/length, true);
    }

    private Vector(double x, double y, double z, boolean isUnitVector){
        // Temp variable for calculating the length
        double length = Math.sqrt(x*x + y*y + z*z);

        if (isUnitVector){
            this.length = 1;

            this.x=x/length;
            this.y=y/length;
            this.z=z/length;

            this.unit = this;
        }else{
            this.length = Math.sqrt(x*x + y*y + z*z);

            this.x=x;
            this.y=y;
            this.z=z;

            this.unit = new Vector(x/length, y/length, z/length, true);
        }

    }

}

我并不完全满意布尔参数后面的构造函数之间的代码复制。实际上,我可能会使用一个静态方法创建一个工厂类,
VectorFactory
,它唯一的任务就是创建向量对象。或者只使用Java自己的
javax.vecmath.Vector3d
和相关类。

我提出了一个构造函数,它决定自己是否是单位向量。如果它是单位向量,则
unit
指向自身。这将中断构造函数的递归。 唯一的问题可能是由于舍入错误,
length
不完全是
1.0
的数字

public class Vector {
    public double x, y, z;
    public Vector unit;

    public Vector(double x, double y, double z){
        this.x = x;
        this.y = y;
        this.z = z;
        double length = calcLength(x, y, z);
        if( length == 1.0 )  // perhaps add a little fuzz factor.
            this.unit = this;
        else
            this.unit = new Vector(x/length, y/length, z/length);
    }
}

好的,谢谢。我之所以把它公之于众,是因为我喜欢做
Vector.unit
Vector.x
而不是
Vector.getX()
。除了正确的语法礼仪之外,它应该是私有的而不是公共的,还有什么重要的原因吗?您将它设置为私有的,以强制客户端使用该方法,而不是直接访问变量;您希望他们使用该方法,以便延迟初始化变量。如果您希望名称更短,可以将其命名为
unit()
。当然需要模糊因子。代码的问题是,当循环重复时,长度将收敛到1。它可能收敛得足够快,以至于if语句的true子句可以在20次递归之后执行。这意味着您可能不会遇到硬错误,但性能会更差。我还没有做这个实验,但要小心!现在我确实试过了,事实上似乎没有什么问题。即使使用非常极端的值,我也无法让它再递归一次。所以这可能不是问题。即使它重复一次,该值也应该收敛得如此之快,从性能角度看这无关紧要。