简体   繁体   English

如果内部 class 是私有的,为什么不允许在外部 class 泛型类型参数中使用内部 class?

[英]Why using inner class in outer class generic type parameter not allowed if inner class is private?

This is maybe a dumb question, but I'm pretty surprised to see that using the private inner class as a generic type in the outer class isn't allowed.这可能是一个愚蠢的问题,但我很惊讶地看到,不允许使用私有内部 class 作为外部 class 中的泛型类型。

If I make the inner class protected, it compiles fine.如果我使内部 class 受保护,它编译得很好。

Additionally, I have to precise Outer.Inner instead of just Inner , otherwise the inner class isn't found.此外,我必须精确Outer.Inner而不仅仅是Inner ,否则找不到内部 class 。 This also looks a little weird.这看起来也有点奇怪。

Why can't Inner be private?为什么 Inner 不能是私有的? And why it is allowed to be protected?为什么允许它受到保护?

public class Outer extends AbstractSet<Outer.Inner> {

  private static class Inner {
    // ...
  }
  
  // ... 
}

The error is:错误是:

Outer.java:3: error: Inner has private access in Outer
public class Outer extends AbstractSet<Outer.Inner> {
                                                   ^
1 error

I'm using Java SE 17, but I think it doesn't matther much.我正在使用 Java SE 17,但我认为这无关紧要。

Note the meaning of private from the language spec §6.6.1 , emphasis mine:请注意语言规范 §6.6.1private的含义,强调我的:

Otherwise, the member or constructor is declared private.否则,成员或构造函数被声明为私有。 Access is permitted only when the access occurs from within the body of the top level class or interface that encloses the declaration of the member or constructor.仅当访问发生在顶级 class 的主体或包含成员或构造函数的声明的接口内时,才允许访问。

The implements clause is not part of the class body. implements子句不是 class 主体的一部分。 The syntax for a class declaration looks like this ( Classes ): class 声明的语法如下所示( ):

NormalClassDeclaration:
{ClassModifier} class TypeIdentifier [TypeParameters] [ClassExtends] 
[ClassImplements] [ClassPermits] ClassBody

ClassBody:
{ {ClassBodyDeclaration} }

The "body" of the class refers strictly to the things inside the curly braces. class 的“主体”严格指花括号内的东西。 Therefore, you cannot access the private class Inner in the implements clause.因此,您无法在implements子句中访问私有 class Inner

If Inner is protected or package-private, on the other hand, then access is allowed, because both of them allows access from the same package.另一方面,如果Inner protected或包私有,则允许访问,因为它们都允许从同一个 package 访问。

Similarly, the scope of a member class declaration is the body of the class too ( §6.3 ):同样,成员class声明的 scope 也是class的主体(§6.3):

The scope of a declaration of a member m declared in or inherited by a class or interface C (§8.2, §9.2) is the entire body of C, including any nested class or interface declarations. The scope of a declaration of a member m declared in or inherited by a class or interface C (§8.2, §9.2) is the entire body of C, including any nested class or interface declarations.

Therefore, the implements clause is not in scope of the Inner class, which is why you need to use a more qualified name to refer to it, rather than its simple name.因此, implements子句不在Inner class 的 scope 中,这就是为什么您需要使用更合格的名称来引用它,而不是它的简单名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM