Why can't I use protected constructors outside the package?
Solution 1
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
}
}
Solution 2
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!
Solution 3
In fact you are already using protected constructor of Example because Check has an implicit constructor and implicit Example constructor call:
public Check() {
super();
}
Abhilash28
Updated on June 05, 2022Comments
-
Abhilash28 about 2 years
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 } }
- Why do i get the error even though i have extended the class? Please explain
EDIT:
Compilation error:
The constructor Example() is not visible
-
TheLostMind about 9 yearsNo.
protected
can be used across packages. You just have to extend the class.default
scope is within a package. The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package. -
Abhilash28 about 9 yearsStill the answer is not convincing, I understand that it will call the parent class consturtor ie> Example() which is protected but as we know we can use protected modifers outside the package if we extend that class then why that doesn't work here in case of constructors?
-
Ya Wang about 9 yearsWhy would you need to call the constructor of a superclass independently? You have access to methods of superclass directly if they are not default access or private.
-
kittu about 9 yearslearned new thing ;)
-
Paul Boddington about 9 years@kittu So did I. I didn't realise there were weird restrictions like that.