通常表示只能由同一包中的子类或类访问。但是,以下是JLS中构造函数的规则:protected
6.6.2.2. 对受保护构造函数的限定访问
设 C 是声明受保护构造函数的类,让 S 是其声明中使用受保护构造函数的最内层类。然后:
如果访问是通过超类构造函数调用 super(...) 或限定的超类构造函数调用 E.super(...),其中 E 是主表达式,则允许访问。
如果访问是通过匿名类实例创建表达式 new C(...){...},或限定的匿名类实例创建表达式 E.new C(...){...},其中 E 是主表达式,则允许访问。
如果访问是通过简单的类实例创建表达式 new C(...) 或限定类实例创建表达式 E.new C(...),其中 E 是主表达式,或方法引用表达式 C :: new,其中 C 是 ClassType,则不允许访问。受保护的构造函数可由类实例创建表达式(不声明匿名类)或方法引用表达式从定义它的包中访问。
例如,这不会编译
public class Example extends Exception {
void method() {
Exception e = new Exception("Hello", null, false, false);
}
}
但这确实
public class Example extends Exception {
Example() {
super("Hello", null, false, false);
}
}
这个也是如此
public class Example {
void method() {
Exception e = new Exception("Hello", null, false, false) {};
}
}
所以规则是明确的,但我不能说我理解它们背后的原因!