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

时间:2022-07-10 16:05:47

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?

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

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

我希望在所有情况下都是错误,或者没有错误。谁能解释一下发生了什么?

2 个解决方案

#1


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.

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

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.

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

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:

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

 Outer<?>.Inner inner;

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

这里Java编译器认为Outer将任何对象作为将继承Object的参数。

#2


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

#1


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.

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

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.

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

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:

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

 Outer<?>.Inner inner;

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

这里Java编译器认为Outer将任何对象作为将继承Object的参数。

#2


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