Why can't I use protected constructors outside the package for this piece of code:
package code; public class Example{ protected Example(){} ... }
Check.java
package test; public class Check extends Example { void m1() { Example ex=new Example(); //compilation error } }
EDIT:
Compilation error:
The constructor Example() is not visible
The protected access modifier is accessible within the package. However, it can also accessible outside the package but through inheritance only. We can't assign protected to outer class and interface. If you make any constructor protected, you cannot create the instance of that class from outside the package.
While protected members can be accessed anywhere in the same package and outside package only in its child class and using the child class's reference variable only, not on the reference variable of the parent class.
Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only. Outer class and interface cannot be protected.
A protected constructor means that only derived members can construct instances of the class (and derived instances) using that constructor. This sounds a bit chicken-and-egg, but is sometimes useful when implementing class factories.
Usually protected
means only accessible to subclasses or classes in the same package. However here are the rules for constructors from the JLS:
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.
As an example, this does not compile
public class Example extends Exception { void method() { Exception e = new Exception("Hello", null, false, false); } }
but this does
public class Example extends Exception { Example() { super("Hello", null, false, false); } }
and so does this
public class Example { void method() { Exception e = new Exception("Hello", null, false, false) {}; } }
So the rules are clear, but I can't say I understand the reasons behind them!
protected modifier is used only with in the package and in sub-classes outside the package. When you create a object using Example ex=new Example();
it will call parent class constructor by default.
As parent class constructor being protected you are getting a compile time error. You need to call the protected constructor according to JSL 6.6.2.2 as shown below in example 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 } }
Example 2 conforming to 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 } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With