2

I recently ran into an issue with my object initialization.

I have a class (It is set up this way for persistent data storing and loading)

public class Example extends SuperExample{
    private String name = "";
    public Example(){
        super();
    }

    public String getName(){
        return name;
    }

    @Override
    protected void load(){
        name = "Example";
    }
}

public abstract class SuperExample{
    protected abstract void load();
    public SuperExample(){
        //Do stuff
        load();
    }
}

The getName() that is called after the object is initialized is returning "" and not "Example".

Any idea what the root cause of this could be? If I were to set name in the constructor it works fine. But when it goes through the super, it errors.

Example e = new Example();
System.out.println(e.getName());
Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
Daniel B
  • 49
  • 2
  • 5
  • 6
    TL;DR: don't call overridable methods in the constructor. – lealceldeiro Jan 21 '20 at 15:37
  • 2
    Instance variable initialiser runs *after* super() calls. Do not call overridable methods from the constructor. – Thiyagu Jan 21 '20 at 15:38
  • https://stackoverflow.com/questions/19407187/java-constructors-order-of-execution-in-an-inheritance-hierarchy – Thiyagu Jan 21 '20 at 15:39
  • Ah ha, Thanks @lealceldeiro Found this after he mentioned. https://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors – Daniel B Jan 21 '20 at 15:40
  • 1
    Does this answer your question? [Are fields initialized before constructor code is run in Java?](https://stackoverflow.com/questions/14805547/are-fields-initialized-before-constructor-code-is-run-in-java) – Thiyagu Jan 21 '20 at 15:42

2 Answers2

1

The initializer code: private String name = ""; runs AFTER the parent constructor. Remove the initialization and it will work correctly. But you shouldn't call overridable methods from constructors. :)

private String name;

instead of

private String name="";
Rex
  • 46
  • 2
  • 1
    In fact it is a **terrible** thing to use a protected load in the super constructor. – Joop Eggen Jan 21 '20 at 15:49
  • This doesn't make correct the fact of calling in a super class's constructor a method that is overridden by subclasses (the root cause of the problem here) – lealceldeiro Jan 21 '20 at 15:53
  • The overridden method is not the root cause of the problem. It is not good programming practice, but the root cause of why name's value is overwritten is as I described. – Rex Jan 21 '20 at 15:59
-1

It's because the Example class method is protected I think. It's not callable from outside the class, so you're calling the superclass method. That does nothing so the value is still "". To check this, add a print statement to the load method and see if it's being called.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263