为什么不能在包外使用受保护的构造函数?
这个问题在这里已经有了答案:
受保护的修饰符仅用于包和包外的子类中。 当你使用Example ex=new Example();
创建一个对象时Example ex=new Example();
它会默认调用父类构造函数。
作为受保护的父类构造函数,您将收到编译时错误。 您需要根据JSL 6.6.2.2调用受保护的构造函数,如以下示例2中所示。
package Super;
public class SuperConstructorCall {
protected SuperConstructorCall() {
}
}
package Child;
import Super.SuperConstructorCall;
public class ChildCall extends SuperConstructorCall
{
public static void main(String[] args) {
SuperConstructorCall s = new SuperConstructorCall(); // Compile time error saying SuperConstructorCall() has protected access in SuperConstructorCall
}
}
符合JLS 6.6.2.2的示例2:
package Super;
public class SuperConstructorCall {
protected SuperConstructorCall() {
}
}
package Child;
import Super.SuperConstructorCall;
public class ChildCall extends SuperConstructorCall
{
public static void main(String[] args) {
SuperConstructorCall s = new SuperConstructorCall(){}; // This will work as the access is by an anonymous class instance creation expression
}
}
通常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) {};
}
}
所以规则很明确,但我不能说我明白他们背后的原因!
事实上,你已经使用了Example的受保护构造函数,因为Check有一个隐含的构造函数和隐式的构造函数调用:
public Check() {
super();
}
链接地址: http://www.djcxy.com/p/24053.html
上一篇: Why cant i use protected constructors outside the package?