I am trying to understand the behavior of protected member in a class. I have a class TopClass
which contains protected integer pr
.
Class:
package com.test;
import com.test.anotherpackage.SubClass1;
import com.test.anotherpackage.SubClass2;
import com.test.anotherpackage.SubClass3;
public class TopClass {
protected int pr;
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 3;
s1.pr = 0;
s2.pr = 1;
s3.pr = 1;
}
}
There is another package com.test.anotherpackage
which has 3 classes SubClass1
, SubClass2
and SubClass3
. Inheritance hierarchy is as follows:
SubClass1 extends TopClass
SubClass2 extends SubClass1
SubClass3 extends SubClass2
SubClass1
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass1 extends TopClass {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0; // Error because not in same package.
s1.pr = 0; //(1)
s2.pr = 1; // Does not throw an Exception. Why? (2)
s3.pr = 1; // (3)
}
}
SubClass2
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass2 extends SubClass1 {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0; // Error because not in same package.
s1.pr = 0; // Throws Exception, why? (4)
s2.pr = 1; // (5)
s3.pr = 1; // Does not throw an Exception. Why?(6)
}
}
SubClass3
package com.test.anotherpackage;
import com.test.TopClass;
public class SubClass3 extends SubClass2 {
void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
t.pr = 0;
s1.pr = 0; // Not Visible (7)
s2.pr = 1; // Not Visible (8)
s3.pr = 1; // (9)
}
}
In above code, (1)
, (2)
, (3)
, (5)
, (6)
and (9)
work perfectly without any visibility issues. But (4)
, (7)
, (8)
have visibility issues.
According to JLS§6.6.2.1 ,
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
Thing I am trying to understand here is why if the type of the expression Q is S or a subclass of S
comes into picture. Is there any specific scenario in which this implementation can be beneficial? Any related example will be highly appreciated. I tried looking it on SO, but couldn't find an explanation which could solve my doubt.
The expression you're discussing is also the one responsible for your questions in the code:
if the type of the expression Q is S or a subclass of S
(2)
because the type of the expression s2
is a subclass of SubClass1
(4)
because the type of the expression s1
is not a subclass of SubClass2
(5)
because the type of the expression s3
is a subclass of SubClass2
However, I don't know of
any specific scenario in which this implementation can be beneficial
either.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.