Why can't I use protected constructors outside the package?
为什么我不能在包外为这段代码使用受保护的构造函数:
1 2 3 4 5 | package code; public class Example{ protected Example(){} ... } |
JAVA
1 2 3 4 5 6 | package test; public class Check extends Example { void m1() { Example ex=new Example(); //compilation error } } |
编辑:
编译错误:
The constructor Example() is not visible
通常,
6.6.2.2. Qualified Access to a protected Constructor
Let C be the class in which a protected constructor is declared and
let S be the innermost class in whose declaration the use of the
protected constructor occurs. Then:If the access is by a superclass constructor invocation super(...),
or a qualified superclass constructor invocation E.super(...), where E
is a Primary expression, then the access is permitted.If the access is by an anonymous class instance creation expression
new C(...){...}, or a qualified anonymous class instance creation
expression E.new C(...){...}, where E is a Primary expression, then
the access is permitted.If the access is by a simple class instance creation expression new
C(...), or a qualified class instance creation expression E.new
C(...), where E is a Primary expression, or a method reference
expression C :: new, where C is a ClassType, then the access is not
permitted. A protected constructor can be accessed by a class instance
creation expression (that does not declare an anonymous class) or a
method reference expression only from within the package in which it
is defined.
作为一个例子,这不会编译
1 2 3 4 5 6 |
但这确实
1 2 3 4 5 6 |
这个也是
1 2 3 4 5 6 |
所以规则是明确的,但我不能说我理解它们背后的原因!
受保护的修饰符只与包内和包外的子类一起使用。使用
作为受保护的父类构造函数,您将收到编译时错误。您需要根据JSL6.6.2.2调用受保护的构造函数,如下面的示例2中所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 } } |
实际上,您已经在使用示例的受保护构造函数,因为check具有隐式构造函数和隐式示例构造函数调用:
1 2 3 | public Check() { super(); } |