1

Is it possible to call a constructor with the result of a method from another constructor of the same class?

I want to be able to accept input in several forms, and have something like:

public class MyClass
{
    public MyClass(int intInput)
    {
    ...
    }

    public MyClass(String stringInput);
    {
        this(convertToInt(stringInput));
    }

    public int convertToInt(String aString)
    {
        return anInt;
    }
}

When I try to compile this, I get

error: cannot reference this before supertype constructor has been called

refering to convertToInt.

DenverCoder8
  • 401
  • 7
  • 15
  • I wouldn't recommend calling a method within the constructor; object construction is supposed to be quick and simple. Perhaps include an `init()` method? – mre Feb 29 '12 at 19:38

3 Answers3

4

You just need to make convertToInt static. Since it doesn't really rely on on anything in the class instance, it probably doesn't really belong on this class anyway.

Here's an example:

class MyClass {
    public MyClass(String string) {
        this(ComplicatedTypeConverter.fromString(string));
    }

    public MyClass(ComplicatedType myType) {
        this.myType = myType;
    }
}

class ComplicatedTypeConverter {
    public static ComplicatedType fromString(String string) {
        return something;
    }
}

You have to do it this way because, behind the scenes, the super-constructor (in this case Object) needs to be called before your own constructor is run. By referring to this (via the method call) before that invisible call to super(); happens you're violating a language constraint.

See the JLS section 8.8.7 and more of the JLS section 12.5.

alpian
  • 4,668
  • 1
  • 18
  • 19
  • Thanks! I realised that just as I was posting the question, so I thought I'd carry on anyway, and answer it myself as well. I haven't just copied your answer, honest! – DenverCoder8 Feb 29 '12 at 19:32
  • This is a simplified version of my code, there isn't a library function for the conversion I need to do. – DenverCoder8 Feb 29 '12 at 19:37
  • Ok, you should just decide if that conversion really belongs to this class, or if it's more generically useful, it should go elsewhere. – alpian Feb 29 '12 at 19:38
2

The method convertToInt can't be called, because it needs to be run by an object, not just from a class. Therefore, changing the code to

public static int convertToInt(String aString)
{
    return anInt;
}

means that convertToInt before the constructor has finished.

DenverCoder8
  • 401
  • 7
  • 15
0

No its not possible. To call instance method all your super class constructor must have been called. In this case you are calling this() which replaces call to super(). You can not have both super() and this() in the same function either. So super class instance is not initialized in your case hence you are getting this error.

You can call like this

public MyClass(String stringInput) {
    super(); // No need to even call... added just for clarification
    int i = convertToInt(stringInput);
}

Making the method static might solve your problem.

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
JProgrammer
  • 1,135
  • 1
  • 10
  • 27
  • It's totally fine to call another constructor from a constructor. See [How do I call one constructor from another in Java?](http://stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java) – Bob Wang Feb 29 '12 at 20:04
  • I never said that you can not call other constructor. Its perfectly fine. I said you can not call this() and super() at the same time in same constructor. – JProgrammer Feb 29 '12 at 20:15
  • It's quite confusing. I don't think he asked such question. – Bob Wang Feb 29 '12 at 21:06