Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use protected constructors outside the package? [duplicate]

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   } } 
  1. Why do i get the error even though i have extended the class? Please explain

EDIT:

Compilation error:

The constructor Example() is not visible

like image 662
Abhilash28 Avatar asked Apr 09 '15 05:04

Abhilash28


People also ask

How do I access a protected method outside the package?

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.

Can protected members be accessed from the same 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.

How do I override a protected constructor in Java?

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.

What happens when a constructor is defined as 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.


2 Answers

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!

like image 111
Paul Boddington Avatar answered Sep 27 '22 19:09

Paul Boddington


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      } } 
like image 38
kittu Avatar answered Sep 27 '22 19:09

kittu