Search code examples
javastack-overflowjogl

Making java wait until a property is called for?


I recently started working with JOGL, so I made a vector class. Inside this class, I used the line

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

To find the unit vector. And of course, this causes a stackoverflow. Is there any way to make java wait for unit to be called before running this or will I have to make unit a method?


Solution

  • I woukld personally create a second constructor, which calculates the unit vector and sets its own unit vector to itself. You should ideally use private values and a get method as Ernest suggests. The reason for this is that otherwise other classes can simply overwrite the x,y,z, etc. values if they have access to one of your objects. Java has a tradition of using final classes for pure data storage. See the String class for example. You can't modify an existing String, only create a new String. Once created, a String remains the same. For your purposes it might not matter much, but in a different context it may cause your application to misbehave, if your class is used by someone who doesn't have a clue. It might even be a security risk in some cases.

    You could simply ignore this and access the variables directly, and enjoy the less cluttered code and small performance increase. But I would still suggest knowing what the problem is for the future.

    Anyway, below is my suggested code for solving the unit vector problem, minus getter methods.

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

    I'm not entirely happy with the code duplication between the constructors that follows from the boolean argument. In practice, I would probably create a factory class, VectorFactory with one static method, whose only job is to create Vector objects. Or maybe just use Java's own javax.vecmath.Vector3d and related classes.