protected
通常意味着只能被子类或同一包中的类访问。然而,以下是JLS中构造函数的规定:
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) {};
}
}
规则很清楚,但我不太理解背后的原因!
public class Example {protected int i;} /* in another package: */ public class Check extends Example {void m1(Example ex) {ex.i = 2;}}
。 - user253751