javainner-classes

Why `Outer.Inner inner = o.new Inner();` not `Outer.Inner inner = o.new Outer.Inner();`?


class Outer {    
    class Inner {       

    }    
}

public class Demo {
    public static void main(String args[]) {

        Outer o = new Outer();
        Outer.Inner inner = o.new Inner();    

    }    
}

Why is

Outer.Inner inner = o.new Inner();

not

Outer.Inner inner = o.new Outer.Inner();

i.e. why qualifying type declaration of inner with outer class name, but not qualifying the inner class' constructor with the outer class name?

Thanks.


Solution

  • From the JLS 15.9, you are talking about a qualified class instance creation expression:

    Qualified class instance creation expressions begin with a Primary expression or an ExpressionName

    (Yours starts with a primary expression)

    The syntax is given as:

    ClassInstanceCreationExpression:
      UnqualifiedClassInstanceCreationExpression
      ExpressionName . UnqualifiedClassInstanceCreationExpression
      Primary . UnqualifiedClassInstanceCreationExpression
    
    UnqualifiedClassInstanceCreationExpression:
      new [TypeArguments] ClassOrInterfaceTypeToInstantiate ( [ArgumentList] ) [ClassBody]
    
    ClassOrInterfaceTypeToInstantiate:
      {Annotation} Identifier {. {Annotation} Identifier} [TypeArgumentsOrDiamond]
    
    TypeArgumentsOrDiamond:
      TypeArguments 
      <>
    

    A bit lower down, in 15.9.1, it says:

    The Identifier in ClassOrInterfaceTypeToInstantiate must unambiguously denote an inner class that is accessible, non-final, not an enum type, and a member of the compile-time type of the Primary expression or the ExpressionName. Otherwise, a compile-time error occurs.

    So, it has to be a member of the type of the expression. As such, there is no need to qualify it, as it cannot be anything but a class inside Outer.

    It would simply be redundant to have to specify the Outer..