让java等待直到调用属性?
我最近开始与JOGL合作,所以我制作了一个向量类。在这个班里,我用了这句话让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()的方法。然后,只需
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次递归之后执行。这意味着您可能不会遇到硬错误,但性能会更差。我还没有做这个实验,但要小心!现在我确实试过了,事实上似乎没有什么问题。即使使用非常极端的值,我也无法让它再递归一次。所以这可能不是问题。即使它重复一次,该值也应该收敛得如此之快,从性能角度看这无关紧要。