【问题标题】:Why using inner class in outer class generic type parameter not allowed if inner class is private?如果内部类是私有的,为什么不允许在外部类泛型类型参数中使用内部类?
【发布时间】:2022-01-25 11:21:14
【问题描述】:

这可能是一个愚蠢的问题,但我很惊讶地看到不允许在外部类中使用私有内部类作为泛型类型。

如果我使内部类受到保护,它编译得很好。

另外,我必须精确到Outer.Inner 而不仅仅是Inner,否则找不到内部类。这看起来也有点奇怪。

为什么 Inner 不能是私有的?为什么允许它被保护?

public class Outer extends AbstractSet<Outer.Inner> {

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

错误是:

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

我正在使用 Java SE 17,但我认为这并不重要。

【问题讨论】:

  • 我认为这是因为当我们创建一个外部类的对象时,它是内部类型的。由于内部是私有的,其他类不能访问。我们不能使泛型类型 Inner 的 Outer...
  • 允许包私有,访问级别更严格。

标签: java


【解决方案1】:

language spec §6.6.1中注意private的含义,强调我的:

否则,成员或构造函数被声明为私有。仅当访问发生在包含成员或构造函数声明的顶级类或接口的 body 内时,才允许访问。

extends 子句不是类主体的一部分。类声明的语法如下所示 (Classes):

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

ClassBody:
{ {ClassBodyDeclaration} }

类的“主体”严格指大括号内的东西。因此,您无法访问extends 子句中的私有类Inner

另一方面,如果Innerprotected 或包私有,则允许访问,因为它们都允许从同一个包进行访问。

同样,成员类声明的范围也是类的主体(§6.3):

在类或接口 C(第 8.2 节、第 9.2 节)中声明或继承的成员 m 的声明范围是 C 的整个主体,包括任何嵌套的类或接口声明。

因此,extends 子句不在Inner 类的范围内,这就是为什么您需要使用更合格的名称来引用它,而不是简单的名称。

【讨论】:

    猜你喜欢
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    相关资源
    最近更新 更多