匿名类可以在超类型的签名中引用不可访问的类型吗?

问题描述 投票:0回答:1

考虑 JLS 8 中的以下条款:§ 15.9.5.1。匿名构造函数

请注意,匿名构造函数的签名可能会引用不可访问的类型(例如,如果此类类型出现在超类构造函数 cs 的签名中)。这本身不会在编译时或运行时导致任何错误。

我尝试为此生成一个示例 - 并提出了以下内容:

.
└── com
    └── example
        ├── inaccessible
        │   └── InaccessibleType.java
        ├── subclass
        │   └── SubClass.java
        └── superclass
            └── SuperClass.java

代码如下:

->

InaccessibleType.java

package com.example.inaccessible;
public class InaccessibleType {
  public void display() {
    System.out.println("InaccessibleType instance");
  }
}

->

SuperClass.java

package com.example.superclass;

// Importing the superclass
import com.example.inaccessible.InaccessibleType;

public class SuperClass {
  public SuperClass(InaccessibleType it) {
    it.display();
  }
}

->

SubClass.java

package com.example.subclass;

import com.example.superclass.SuperClass;

public class SubClass {
  public static void main(String[] args) {
    // Creating an anonymous class that extends SuperClass
    SuperClass instance = new SuperClass(new InaccessibleType() {
      // This anonymous class does not have access to InaccessibleType
    }) {
      // Anonymous constructor referring to InaccessibleType
      // No errors here even though InaccessibleType is inaccessible
    };
  }
}

现在,尽管 JLS 中给出了上述声明 - 我仍然在子类中遇到编译错误

javac com/example/inaccessible/*.java com/example/subclass/*.java com/example/superclass/*.java                                                                                    ─╯
com/example/subclass/SubClass.java:8: error: cannot find symbol
    SuperClass instance = new SuperClass(new InaccessibleType() {
                                             ^
  symbol:   class InaccessibleType
  location: class SubClass
1 error

现在确定 - 我对上述条款的理解是否正确? - 正确解释上述条款的例子是什么?

java anonymous-class jls
1个回答
0
投票

在这种情况下,“无法访问”并不意味着“无法使用其简单名称来引用它”。这意味着“根据访问控制的规则无法访问”。

根据访问控制规则,

InaccessibleType
Subclass
中完全可以访问,因为它是
public
。您只需说
com.example.inaccessible.InaccessibleType
,或者如果您导入它,则说
InaccessibleType

JLS 所谈论的情况的一个例子是,

public class Superclass {
    private static class Nested {}

    public Superclass(Nested n) {}
}

Superclass.Nested

 之外无法访问 
Superclass
。在其他一些类中,我可以创建一个继承的匿名类
Superclass
:

new Superclass(null) { };

这个匿名类将有一个构造函数,该构造函数采用

Superclass.Nested
类型的参数。 JLS 说这没问题。此代码按预期编译并运行。

相反,您不能创建具有相同签名的构造函数的

Superclass
的非匿名子类:

class Subclass extends Superclass {

    public Subclass(Superclass.Nested n) { // This will produce an error
        super(n);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.