无法从静态上下文引用内部类,但仅限于外部类是通用的

时间:2015-05-07 09:53:51

标签: java generics inner-classes

以下内容无法编译:

class Outer<T> {
    class Inner {

    }

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

但是,如果我删除<T>,它就会编译。为什么不一致?

另外,如果我说Outer.Inner inner;而不是Inner inner;,则会编译。再次,为什么不一致?

我预计所有情况都会出错或没有错误。谁能解释一下发生了什么?

2 个答案:

答案 0 :(得分:4)

为什么不一致?

我想说这根本不是一致的。这基本上是理解泛型的问题。请考虑以下代码(您修改过的代码):

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

    static class Nested {
        Inner inner; 
    }
}

在上面的示例中,有些类似于您所编写的内容,我添加了类型t的新变量T,它是类{Outer类的泛型1}}。现在在上面的示例中不会编译,因为Inner类中存在非静态或运行时引用,因此,当您在静态类Inner中声明Inner时,JAVA编译器不知道Nested的类型,它只在运行时声明,所以你得到一个错误。但在你的情况下,你没有做过这样的事情,但编译器仍然不知道是否存在类似的东西。所以它给出了错误。

现在在第二种情况下,您已从T的类声明中删除了通用T。因此,不可能在Outer类中声明变量t,因此没有错误。

在第三种情况下,您为变量Inner的类型声明了Outer.Inner并且它已成功编译。这里编译器将inner视为 RAW TYPE 。但是应该避免这种类型的原始类型声明。所以最好写一下:

Outer

这里Java编译器认为 Outer<?>.Inner inner; 将任何对象作为继承Outer的参数。

答案 1 :(得分:1)

class OuterClass {

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

嵌套类是其封闭类的成员。非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。静态嵌套类无权访问封闭类的其他成员。

Static Nested Classes

与类方法和变量一样,静态嵌套类与其外部类相关联。和静态类方法一样,静态嵌套类不能直接引用其封闭类中定义的实例变量或方法:它只能通过对象引用来使用它们。

使用封闭的类名访问静态嵌套类:

OuterClass.StaticNestedClass

例如,要为静态嵌套类创建对象,请使用以下语法:

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

有关详细信息,请参阅以下内容:

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