Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no enclosing instance of type... in scope

I investigate java inner classes.

I wrote example:

public class Outer {
    public Outer(int a){}

    public class Inner {
        public Inner(String str, Boolean b){}
    }

    public static class Nested extends Inner{
        public static void m(){
            System.out.println("hello");
        }
        public Nested(String str, Boolean b , Number nm)   { super("2",true);   }
    }

    public class InnerTest extends Nested{
        public InnerTest(){  super("str",true,12);  }
    }
}

I invoke it from main using following string:

 new Outer(1).new Inner("",true);

I see compile error:

  java: no enclosing instance of type testInheritancefromInner.Outer is in scope

Can you explain me this situation?

UPDATE

enter image description here

like image 595
gstackoverflow Avatar asked Mar 01 '14 16:03

gstackoverflow


People also ask

What does no enclosing instance mean in Java?

The java No enclosing instance of type is accessible. Must qualify the allocation with an enclosing instance of type (e.g. x.new A() where x is an instance of ). exception happens when an instance is created for an inner class in the outer class static method.

What are nested classes in Java?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.

How do you create an inner class in Java?

Creating an inner class is quite simple. You just need to write a class within a class. Unlike a class, an inner class can be private and once you declare an inner class private, it cannot be accessed from an object outside the class.


2 Answers

Inner is an inner class. It can only be created when there is an enclosing instance of the class containing the Inner class definition.

However, you've created a static nested class, Nested, which extends from this class. When you try to invoke the super constructor

public Nested(String str, Boolean b , Number nm)   { super("2",true);   }

it will fail because the super constructor, for Inner, depends on an instance of Outer, which doesn't exist in the static context of the Nested class. Jon Skeet provides a solution.

An explanation of the solution appears in the JLS here.

Superclass constructor invocations may be subdivided:

  • Unqualified superclass constructor invocations begin with the keyword super (possibly prefaced with explicit type arguments).

  • Qualified superclass constructor invocations begin with a Primary expression.

    • They allow a subclass constructor to explicitly specify the newly created object's immediately enclosing instance with respect to the direct superclass (§8.1.3). This may be necessary when the superclass is an inner class.
like image 117
Sotirios Delimanolis Avatar answered Sep 17 '22 17:09

Sotirios Delimanolis


As Sotirios has said, your nested (not-inner) class doesn't implicitly have an instance of Outer to effectively provide to the Inner.

You can get round this, however, by explicitly specifying it before the .super part:

public Nested(String str, Boolean b, Number nm) { 
    new Outer(10).super("2", true);
}

Or even accept it as a parameter:

public Nested(Outer outer) { 
    outer.super("2", true);
}

However, I would strongly advise you to avoid such convoluted code. I avoid nested classes most of the time, named inner classes almost always, and I can't ever remember using a combination of them like this.

like image 34
Jon Skeet Avatar answered Sep 19 '22 17:09

Jon Skeet