为什么我不能在包外使用受保护的构造函数?

为什么我不能在包之外使用受保护的构造函数来获取这段代码:

package code; public class Example{ protected Example(){} ... } 

Check.java

 package test; public class Check extends Example { void m1() { Example ex=new Example(); //compilation error } } 
  1. 为什么即使我延长了课程,我也会得到错误? 请解释

编辑:

编译错误:

构造函数Example()不可见

protected modifier仅在包中和包外的子类中使用。 使用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 } } 

示例2符合JLS 6.6.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的protected构造函数,因为Check有一个隐式构造函数和隐式的Example构造函数调用:

 public Check() { super(); }