JLS中匿名类引用超类签名不可访问类型的示例疑问
关于JLS 8 §15.9.5.1匿名构造函数条款的理解与正确示例
你的理解偏差
你对JLS条款的理解存在偏差。你编写的代码编译错误,并不是因为匿名构造函数引用不可访问类型导致的,而是直接在SubClass的主代码中引用了对它不可见的InaccessibleType类——SubClass所在包未导入该类,也没有权限访问,因此编译器报错“找不到符号”,这和匿名构造函数本身无关。
JLS §15.9.5.1的条款核心是:匿名构造函数的签名(隐式生成的,用于调用超类构造函数)中如果引用了不可访问的类型,这本身不会引发编译或运行时错误。这里的关键是“匿名构造函数的签名”,而非你在代码中显式引用不可访问类型。
正确的验证示例
我们需要构造这样的场景:超类构造函数的参数类型对当前类不可访问,但我们不需要显式引用该类型,而是通过其他合法方式获取该类型的实例,此时匿名类的隐式构造函数会引用这个不可访问类型,但编译依然正常。
代码结构与实现
com/example/inaccessible/InaccessibleType.java(设置为包访问权限,仅同包可见)
package com.example.inaccessible; // 去掉public修饰符,仅本包可访问 class InaccessibleType { public void display() { System.out.println("InaccessibleType instance"); } }
com/example/superclass/SuperClass.java(提供静态方法返回不可访问类型的实例)
package com.example.superclass; import com.example.inaccessible.InaccessibleType; public class SuperClass { public SuperClass(InaccessibleType it) { it.display(); } // 提供静态方法,让外部类无需直接引用InaccessibleType就能获取其实例 public static InaccessibleType getInaccessibleInstance() { return new InaccessibleType(); } }
com/example/subclass/SubClass.java(通过超类的静态方法获取实例,创建匿名子类)
package com.example.subclass; import com.example.superclass.SuperClass; public class SubClass { public static void main(String[] args) { // 通过SuperClass的静态方法获取实例,无需直接引用InaccessibleType SuperClass instance = new SuperClass(SuperClass.getInaccessibleInstance()) { // 匿名类的隐式构造函数签名会引用InaccessibleType(超类构造参数类型) // 但无需显式编写,编译不会报错,符合JLS条款描述 }; } }
编译与运行验证
执行编译命令:
javac com/example/inaccessible/*.java com/example/subclass/*.java com/example/superclass/*.java
此时编译不会报错,运行SubClass会输出:
InaccessibleType instance
这个示例符合JLS条款的描述:匿名类的隐式构造函数签名引用了对SubClass不可访问的InaccessibleType,但这并没有导致编译或运行时错误。
内容的提问来源于stack exchange,提问作者theutonium.18
相关产品推荐
相关产品推荐

