Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't reference inner class from a static context, but only if outer class is generic

The following won't compile:

class Outer<T> {
    class Inner {

    }

    static class Nested {
        Inner inner; // Error: Outer.this cannot be referenced from a static context
    }
}

However, if I remove <T>, it compiles. Why the inconsistency?

Also, if I say Outer.Inner inner;, instead of Inner inner;, it compiles. Again, why the inconsistency?

I'd expect an error in either all cases or none. Could anyone explain what's going on?

like image 401
Tom Avatar asked May 07 '15 09:05

Tom


2 Answers

Why the inconsistency?

I would say this is not inconsistency at all. This is basically a problem of understanding of generics. Consider the following code (Your modified code):

class Outer<T> {
    class Inner{
        T t;//Added this extra line
    }

    static class Nested {
        Inner inner; 
    }
}

In this above example is somewhat similar to what you have written only I have added a new variable t of type T which is the generics of Outer class in the class Inner. Now in this above example would not compile because there is a non-static or runtime reference present in the Inner class, so, when you declare Inner in a static class Nested the JAVA complier does not know the type of T, which is only declared in the runtime, so you get an error. But in your case you have done nothing like that but still the compiler does not know whether something like that is present or not. So it gives the error.

Now in the second case you have removed the generic T from the class declaration of the Outer. So there is no possibility of declaring variable t in the Inner class so there is no error.

In the third case you declared Outer.Inner for the type of variable inner and it compiled successfully. Here the compiler considered Outer as RAW TYPE. But this type of raw type declarations should be avoided. So it would be better to write:

 Outer<?>.Inner inner;

Here Java compiler considers Outer to take any object as parameters which would inherit Object.

like image 124
Blip Avatar answered Oct 20 '22 15:10

Blip


class OuterClass {

    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}

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.

Static Nested Classes

As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class: it can use them only through an object reference.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass();

For more information see the below click:

https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

like image 26
Anil Reddy Yarragonda Avatar answered Oct 20 '22 15:10

Anil Reddy Yarragonda