考虑 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
现在确定 - 我对上述条款的理解是否正确? - 正确解释上述条款的例子是什么?
在这种情况下,“无法访问”并不意味着“无法使用其简单名称来引用它”。这意味着“根据访问控制的规则无法访问”。
根据访问控制规则,
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);
}
}