Why can't we instantiate a class with a protected constructor if its child is in a different package? If protected variables and methods can be accessed, why doesn't the same rule also apply for a protected constructor?
pack1:
package pack1; public class A { private int a; protected int b; public int c; protected A() { a = 10; b = 20; c = 30; } }
pack2:
package pack2; import pack1.A; class B extends A { public void test() { A obj = new A(); // gives compilation error; why? //System.out.println("print private not possible :" + a); System.out.println("print protected possible :" + b); System.out.println("print public possible :" + c); } } class C { public static void main(String args[]) { A a = new A(); // gives compilation error; why? B b = new B(); b.test(); } }
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.
Protected members cannot be accessed from the non-child class of outside package. Package members cannot be accessed from non-child class of outside package. Public modifier is the most accessible modifier among all modifiers.
Access specifiers/modifiers allowed with constructorsModifiers public, protected and, private are allowed with constructors.
Like methods, constructors can have any of the access modifiers: public, protected, private, or none (often called package or friendly). Unlike methods, constructors can take only access modifiers. Therefore, constructors cannot be abstract , final , native , static , or synchronized .
According to the Java Spec (https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.2)
6.6.2.2. Qualified Access to a
protected
ConstructorLet
C
be the class in which aprotected
constructor is declared and letS
be the innermost class in whose declaration the use of theprotected
constructor occurs. Then:
If the access is by a superclass constructor invocation
super(...)
, or a qualified superclass constructor invocationE.super(...)
, whereE
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 expressionE.new C(...){...}
, whereE
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 expressionE.new C(...)
, whereE
is a Primary expression, or a method reference expressionC :: new
, whereC
is a ClassType, then the access is not permitted. Aprotected
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.
In your case, access to the protected constructor of A
from B
would be legal from a constructor of B
through an invocation of super()
. However, access using new
is not legal.
JLS 6.6.7 answers your question. A subclass only access a protected members of its parent class, if it involves implementation of its parent. Therefore , you can not instantiate a parent object in a child class, if parent constructor is protected and it is in different package...
6.6.7 Example: protected Fields, Methods, and Constructors Consider this example, where the points package declares:
package points; public class Point { protected int x, y; void warp(threePoint.Point3d a) { if (a.z > 0) // compile-time error: cannot access a.z a.delta(this); } }
and the threePoint package declares:
package threePoint; import points.Point; public class Point3d extends Point { protected int z; public void delta(Point p) { p.x += this.x; // compile-time error: cannot access p.x p.y += this.y; // compile-time error: cannot access p.y } public void delta3d(Point3d q) { q.x += this.x; q.y += this.y; q.z += this.z; } }
which defines a class Point3d. A compile-time error occurs in the method delta here: it cannot access the protected members x and y of its parameter p, because while Point3d (the class in which the references to fields x and y occur) is a subclass of Point (the class in which x and y are declared), it is not involved in the implementation of a Point (the type of the parameter p). The method delta3d can access the protected members of its parameter q, because the class Point3d is a subclass of Point and is involved in the implementation of a Point3d. The method delta could try to cast (§5.5, §15.16) its parameter to be a Point3d, but this cast would fail, causing an exception, if the class of p at run time were not Point3d.
A compile-time error also occurs in the method warp: it cannot access the protected member z of its parameter a, because while the class Point (the class in which the reference to field z occurs) is involved in the implementation of a Point3d (the type of the parameter a), it is not a subclass of Point3d (the class in which z is declared).
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