St.Antario
St.Antario

Reputation: 27385

How to invoke inner-class constructor?

I've the following classes:

package org.gradle;

public class Supcl {

    public class Inner extends Supsupcl {
        public Inner(int a) {
            System.out.println(a);
        }
    }
}

and

package org.gradle;

public class Subcl extends Supcl.Inner {

    public Subcl() {
        Supcl.Inner.super(34); //error: No enclosing instance of type Supcl is 
                               //available due to some 
                               //intermediate constructor invocation

    }
}

And class Supsupcl:

package org.gradle;

public class Supsupcl {}

If I try to replace Supcl.Inner.super(34); with super(34); the same error will occur. How do it do?

Upvotes: 0

Views: 7738

Answers (3)

Flash
Flash

Reputation: 1125

Make the inner static

public static class InnerClass {

} 

and access it like

ParentClass.InnerClass innerClass = new ParentClass.InnerClass(args); 

where args is your custom parameters if you have any

Upvotes: 1

Thomas
Thomas

Reputation: 88707

Since non-static inner classes have a special relationship with their outer class you always need an instance of the outer class to create an instance of the inner class.

In your case, where a non-inner class extends an inner class, you'll need to either create an instance of the outer class or pass it:

public class Subcl extends Supcl.Inner {
  public Subcl() {
    //assuming there is a no-argument constructor Supcl()
    //this only works in one statement so the call to super is still 
    //part of the first statment in this constructor
    new Supcl().super(34); //will call Inner(34)
  }

  public Subcl( Supcl sup) {
    sup.super(34);  //will call Inner(34)
  }
}

Note that you'd have to do this even if Inner had a no-argument constructor, since you need to somehow get the instance of Supcl and the compiler can't deduce this.

Finally a word of advise (although it is primarily my opinion): as you can see the syntax for inner classes is not always straight forward and it might be hard to grasp what's going on in some cases, thus I'd suggest using inner classes only in simple cases and only if you really need them. It will make your life a lot easier :)

Upvotes: 1

Mena
Mena

Reputation: 48404

You are referencing an inner class nested to the instance of Supcl, so the right idiom to initialize the inner class is:

new Supcl().new Inner(int i)
(assuming Supcl has a 0-argument constructor or the default constructor)

You cannot invoke super outside the constructor, so you'll have to invoke it as the first line of your Inner(int i) constructor code.

Upvotes: 6

Related Questions