当前位置: 首页 > 知识库问答 >
问题:

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

齐元章
2023-03-14

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

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

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

为什么内心不能是私密的?为什么它被允许受到保护?

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

我使用的是JavaSE17,但我认为它并没有太大用处。

共有1个答案

苏丰茂
2023-03-14

注意语言规范§6.6.1中私有的含义,强调我的:

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

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

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

ClassBody:
{ {ClassBodyDeclaration} }

类的“body”严格地指的是花括号中的东西。因此,您无法访问implements子句中的私有类internal

另一方面,如果内部protected或包私有的,则允许访问,因为它们都允许从同一个包访问。

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

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

因此,实现子句不在内部类的范围内,这就是为什么您需要使用一个更有限定性的名称来引用它,而不是它的简单名称。

 类似资料:
  • 我有一个实现Iterable的类,以便用户可以使用迭代器。我使用泛型来允许用户使用任何类型并使用该类。 这是下面的工作代码,没有警告- 但是,如果我将ListIterator定义如下- 我在 Eclipse 中收到警告, 当我在类后指定泛型类型时,它为什么会抱怨?为了能够在我的类中使用Type,我不应该这样做吗?我在定义CustomStackUsingArray时添加了类型,效果很好。

  • 问题内容: 我的代码中有内部类。我想授予对其实例的公共访问权限,但是只有外部类才可以创建此实例,就像在“私有”访问权限中一样。是否可以不做适当的小包装(或为每个这样的内部类创建公共接口)? (对不起,如果我的英语不好:P) 问题答案: 有可能的。将 内部类 声明为 public,但将其构造函数声明为private 。这样,您只能在封闭的类及其内部内部创建它,而不能从外部创建它。

  • 为什么我不能这样做/是否有解决方法来实现这一点: 这两个编译错误是 > On

  • 问题内容: 我试图在这样的泛型类中创建一个常规的RuntimeException: 这段代码使我对这个词的错误说法。 这个RuntimeException与我的类通用有什么关系? 问题答案: Java不允许Throwable的通用子类。而且,非静态内部类可以通过其外部类的类型参数有效地进行参数化(请参见Oracle JDK Bug 5086027 )。例如,在您的示例中,内部类的实例具有form类

  • 问题内容: 我观察到外部类可以访问内部类的私有实例变量。这怎么可能?这是演示相同代码的示例代码: 为什么允许这种行为? 问题答案: 内部类只是一种将真正属于原始外部类的功能完全分开的方法。当你有两个要求时,可以使用它们: 如果是在单独的类中实现的,那么外部类中的某些功能将最为清晰。 即使在单独的类中,该功能也与外部类的工作方式紧密相关。 鉴于这些要求,内部类可以完全访问其外部类。由于它们基本上是外

  • 我必须在Java中实现一个名为的接口。 假设是我编写的实现graph的类。 我想创建一个内部类以便“封装”类型的元素。 问题是我不明白内部类应该是还是、还是以及它的实例变量应该声明为还是。对于我将要在中插入的一些最终方法也是如此。 基本上,类节点应该像C语言中的记录类型(带有),并且外部类应该能够访问节点的所有实例变量,而不需要观察器、getter等。