1

I'am learning Java and I got an unexpected output. That's the code:

public class Point {
    protected final int x,y;
    private final String name;

    public Point(int x,int y){
        this.x = x;
        this.y = y;
        name = makeName();
    }

    protected String makeName() {

        return "["+x+" ,"+y+"]";
    }
    public final String toString(){
        return name;
    }
}
public class ColorPoint extends Point{
    private final String color;

    public ColorPoint(int x,int y, String color){
        super(x,y);
        this.color = color;
    }

    protected String makeName(){
        return super.makeName() + ":" + color;
    }

    public static void main (String[] args){
        System.out.println(
                new ColorPoint(4,2,"viola"));
    }
}

The output is: [4,2]:null.
Why? Shouldn't it be just [4,2] because the variable String name is initialized first in makeName() method of the Point class and then should become unmutable? Am I wrong?

0

6 Answers 6

2

the makeName() method is called before you set this.color = color;

The makeName() method is called by your super.construtctor when the color variable is still null.

Sign up to request clarification or add additional context in comments.

2 Comments

so the makeName() method called is the method of ColorPoint class ?
yes. the makeName method in ColorPoint overrides the super method, and you are calling colorPoint.makeName();
0

super(x,y) is calling method makeName() of ColorPoint class and color is not assigned till then.

Comments

0

Flow is like this,

Point constructor > makeName of ColorPoint > makeName of Point

since, makeName of ColorPoint is called first, till that time color property value was not assigned, so its giving null

Comments

0

makeName() is called in the constructor of the superclass. When it is called color is not yet set so the default value of color is null.

To solve the problem you have to explicitly call makeName() at the end of constructor. Here is the correct code:

public ColorPoint(int x,int y, String color){
    super(x,y);
    this.color = color;
    makeName();
}

Comments

0
 new ColorPoint(4,2,"viola"));

calls the constructor on line 22 , which inturn calls the constructor on line 5 the constructor on line 5 calls the overridden function make name on line 27 which sets name as [4,2]:null because colour hasnt been initialized yet.

Comments

0

final fields are initialized with default values (which for references is null). You can easily check it with this code:

class FinalTest{
    public final String value = test();

    private String test() {
        System.out.println("current state of value is '"+value+"'");
        return "foo";
    }

    public static void main(String[] args) {
        FinalTest ft = new FinalTest();
        System.out.println(ft.value);
    }
}

which produces output:

current state of value is 'null'
foo

So as you see final variable has its default value which can be later modified in constructor once.

But lets get back to your example. When you call

System.out.println(new ColorPoint(4, 2, "viola"));

you are creating invoking constructor of ColorPoint class, and then on this instance toString will be called. But lets take a closer look at ColorPoint constructor:

public ColorPoint(int x, int y, String color) {
    super(x, y);
    this.color = color;
}

As you see before this.color will be set you are invoking super(x,y) which code looks like this:

public Point(int x, int y) {
    this.x = x;
    this.y = y;
    name = makeName();
}

But here in makeName(); thanks to polymorphism (late binding) you are using code of makeName from ColorPoint class which looks like

protected String makeName() {
    return super.makeName() + ":" + color;
}

So at start you will get result of super.makeName() which is "[" + x + " ," + y + "]" but then you are trying to access color which as you remember is not initialized with because

super(x, y); //<-- we are still here
this.color = color;//this wasn't invoked (yet)

so color still has its default value (null).

This means that name will be set to [4 ,2]:null.

Since ColorPoint inherits toString from Point which looks like

public final String toString() {
    return name;
}

you see as output value stored in name which is [4 ,2]:null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.