我最近开始使用JOGL,所以我做了一个矢量类。在这个课程中,我使用了
行 public Vector unit=new Vector(x/length,y/length,z/length);
找到单位矢量。当然,这会导致堆栈溢出。有没有办法让java在运行之前等待单元被调用,或者我必须使单元成为方法吗?
答案 0 :(得分:1)
是的,这很容易,但你需要稍微修改一下你的设计。最重要的是,对于所有成员变量几乎总是如此,unit
应该是私有,并且对它的所有访问都应该通过名为getUnit()
的方法进行。然后,您只需编写getUnit()
来检查unit
是否已初始化:
public synchronized Vector getUnit() {
if (unit == null)
unit = new Vector(x/length,y/length,z/length);
return unit;
}
我已经使用了这个方法synchronized
,这样如果两个不同的线程几乎同时调用getUnit()
并且unit
尚未初始化,则可以避免任何问题
答案 1 :(得分:1)
我woukld亲自创建第二个构造函数,它计算单位向量并将自己的单位向量设置为自身。理想情况下,你应该像Ernest建议的那样使用私有值和get方法。这样做的原因是,如果其他类可以访问您的某个对象,则可以简单地覆盖x,y,z等值。 Java具有使用最终类进行纯数据存储的传统。例如,请参阅String
类。您无法修改现有String
,只能创建新的String
。创建后,String
保持不变。出于您的目的,它可能并不重要,但在不同的环境中,如果您的课程被没有线索的人使用,则可能会导致您的应用程序行为异常。在某些情况下甚至可能存在安全风险。
您可以简单地忽略它并直接访问变量,享受更简洁的代码和小的性能提升。但我仍然建议知道未来的问题是什么。
无论如何,下面是我建议的解决单位向量问题的代码,减去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);
}
}
}
我对从boolean参数后面的构造函数之间的代码重复感到不满意。在实践中,我可能会使用一个静态方法创建一个工厂类VectorFactory
,其唯一的工作是创建Vector对象。或者也许只使用Java自己的javax.vecmath.Vector3d
及相关类。
答案 2 :(得分:0)
我提出了一个构造函数,它决定它是否是一个单位向量。如果它是单位向量,则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);
}
}