Henry A. Henry A. - 3 months ago 8
Java Question

How does the flow of object creation work in Java?

New to Java and OOP in general here.

I'm trying to understand when an object's members are able to be used. Specifically, why can't I pass an instance variable to a constructor when calling it within the class? Example code below:

public class Point {

public String name;

{
name = "Henry";
}

public Point()
{
this(this.name); // cannot reference this before supertype constructor has been called
}

public Point(String name)
{
this.name = name;
}

}


Something like this has been asked before, but I didn't know how to ask Google what I'm explaining here. I know I can't reference
this.name
within the
this(this.name)
call because an object reference hasn't been created yet, but how exactly is Java calling the constructor?

The only time that constructor is going to be executed is when an object is created using
new Point()
, by which time an object reference will be available, and the compiler wouldn't have anything to complain about. If it was possible to assign
this.name
to a variable, and then pass that to
this(variable)
, it would work would it not? What is the huge difference? I'm completely misunderstanding something here.

This is how I'm visualizing it, which is clearly not correct:

Point myPoint = new Point();


myPoint.name
now equals
"Henry"


within the
Point()
constructor, execute
this(this.name) // which should be "Henry"

Answer

The only time that constructor is going to be executed is when an object is created using new Point(), by which time an object reference will be available, and the compiler wouldn't have anything to complain about.

I'd say that the key point here is that the object reference is only available after the constructor has been called. Hence referencing this during the constructor's operation doesn't really make sense.

Also remember that with inheritance, you can have multiple constructors being called before a particular object is instantiated/created. For example:

public class ParentPoint {
    public String name = "Parent Point";

    public ParentPoint() {
        // do something
    }
}

public class Point extends ParentPoint {

    public Point() {
        super();
        // do something else
    }

}

In this case you'll have two constructors that are called before Point is fully instantiated (so the flow you mention in your OP isn't always that straightforward).

Xavier Silva's answer code is a good one, and also having getters and setters would be ideal too:

public class Point {

    public String name = "Henry";

    public Point() {

    }

    public Point(String name) {
        this.name = name; //changes current value (Henry) to the one sent as an argument.
    }

    public void setName(String newName) {
        this.name = newName;
    }

    public String getName() {
        return this.name;
    }


    public static void main(String[] args) {
        Point pointA = new Point();
        Point pointB = new Point("Other name");

        System.out.println(pointA.name); // Henry
        System.out.println(pointB.name); // Other name

        pointA.setName("New name");
        System.out.println(pointA.getName()); // New name
    }
}

The final bit demonstrates getters and setters, the rest of the code is unmodified.