Here is the following code:
package ab:
public class A {
protected static int var = 10;
protected int var2 = 20;
}
and
package cd;
public class C extends A {
A test;
public C(){
test = new A();
}
void printValues(){
System.out.println(A.var); //this is perfectly visible
System.out.println(test.var2); // here I get error saying var2 is not visible
}
}
I cannot understand why static protected field is accessible though A in different package...
Since the fact that a protected
member is accessible from a subclass in any package is widely familiar, I am answering the flip side of your question: Why is the protected
instance field not visible to the subclass?
As usual, the place to look for the authoritative answer is the Java Language Specification, in this case Section 6.6.2. I am quoting the example found there because it is much easier to follow than the legalese that precedes it.
TL;DR: The best way to think of it is this: protected
is an inherited class internal. From the perspective of all its subclasses, A.var2
behaves like a private member of each subclass individually and not a member of the superclass. And all this is in place because protected
is intended to be used in a class designed for extension, so that the subclasses can access those parts which are considered public API for the extending class, but not for the client of the class.
To complete your series of examples I submit two more:
System.out.println(this.var2); // works---intended use of protected
System.out.println(((A)this).var2); // fails same as your test.var2
Food for thought :)
Example 6.6.2-1. Access to 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; } }
A compile-time error occurs in the method
delta
here: it cannot access the protected membersx
andy
of its parameterp
, because whilePoint3d
(the class in which the references to fieldsx
andy
occur) is a subclass ofPoint
(the class in whichx
andy
are declared), it is not involved in the implementation of aPoint
(the type of the parameterp
). The methoddelta3d
can access the protected members of its parameterq
, because the classPoint3d
is a subclass ofPoint
and is involved in the implementation of aPoint3d
.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 notPoint3d
.A compile-time error also occurs in the method
warp
: it cannot access the protected memberz
of its parametera
, because while the classPoint
(the class in which the reference to fieldz
occurs) is involved in the implementation of aPoint3d
(the type of the parametera
), it is not a subclass ofPoint3d
(the class in whichz
is declared).
Protected means that all subclasses get access to it, and all other classes in the same package. In this case, C
is a subclass of A
and thus get access to the fields, regardless of the package it is in.
The subclass C
can't access a protected field of any other A
object though, only of C
objects. So it can access this.var2
, and if you change A test;
into C test;
(and the initialization into test = new C();
, you are able to access it.
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