Is it possible to do computation before super() in the constructor?


Given that I have a class Base that has a single argument constructor with a TextBox object as it's argument. If I have a class Simple of the following form:

public class Simple extends Base {
  public Simple(){
    TextBox t = new TextBox();
    super(t);
    //wouldn't it be nice if I could do things with t down here?
  }
}

I will get a error telling me that the call to super must be the first call in a constructor. However, oddly enough, I can do this.

public class Simple extends Base {
  public Simple(){
    super(new TextBox());
  }
}

Why is it that this is permited, but the first example is not? I can understand needing to setup the subclass first, and perhaps not allowing object variables to be instantiated before the super-constructor is called. But t is clearly a method (local) variable, so why not allow it?

Is there a way to get around this limitation? Is there a good and safe way to hold variables to things you might construct BEFORE calling super but AFTER you have entered the constructor? Or, more generically, allowing for computation to be done before super is actually called, but within the constructor?

Thank you.



Yes, there is a workaround for your simple case. You can create a private constructor that takes TextBox as an argument and call that from your public constructor.

public class Simple extends Base {
    private Simple(TextBox t) {
        super(t);
        // continue doing stuff with t here
    }

    public Simple() {
        this(new TextBox());
    }
}

For more complicated stuff, you need to use a factory or a static factory method.


I had the same problem with computation before super call. Sometimes you want to check some conditions before calling super(). For example, you have a class that uses a lot of resources when created. the sub-class wants some extra data and might want to check them first, before calling the super-constructor. There is a simple way around this problem. might look a bit strange, but it works well:

Use a private static method inside your class that returns the argument of the super-constructor and make your checks inside:

public class Simple extends Base {
  public Simple(){
    super(createTextBox());
  }

  private static TextBox createTextBox() {
    TextBox t = new TextBox();
    t.doSomething();
    // ... or more
    return t;
  }
}

It is required by the language in order to ensure that the superclass is reliably constructed first. In particular, "If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass."

In your example, the superclass may rely on the state of t at construction time. You can always ask for a copy later.

There's an extensive discussion here and here.