Reputation: 3
package p1;
public class MyClass1 {
protected static String str = "ss1";
}
package p2;
import p1.MyClass1;
public class MyClass2 extends MyClass1 {
public static void test(){
MyClass1 mc1 = new MyClass1();
System.out.println(mc1.str);
}
}
As I understand it, the print statement will not work if the String is declared as protected as it is not visible from a different package. But why does it work when is declared as static protected ?
Upvotes: 0
Views: 1059
Reputation: 1428
static modifier has nothing to do with visibility, so nothing will change. You can't access protected member (i.e. field, method) from different package, no matter if it's static or not.
But in your case, MyClass2 extends MyClass1. You can access protected members from superclass. Still, static has nothing to do with this.
EDIT:
Well, this is a very interesting case because there are involved two separate things: 1) Accessing protected members from subclass in different package, 2) Syntax trick allowing you to access static (class) members like instance members.
I will extend your example to show what actually are you doing in this code:
package p1;
public class MyClass1 {
protected String protectedString = "example";
protected static String protectedStaticString = "example";
}
package p2;
import p1.MyClass1;
public class MyClass2 extends MyClass1 {
public void testProtected() {
MyClass1 otherMC1 = new MyClass1();
MyClass2 otherMC2 = new MyClass2();
String testProtected;
testProtected = this.protectedString; // OK, protectedString is inherited, so it's instance member of this class
testProtected = super.protectedString; // OK, it's also instance member of superclass
testProtected = otherMC1.protectedString; // ERROR. You can't access protected members of other instance of superclass
testProtected = otherMC2.protectedString; // OK. As it's inherited member of MyClass2, you can access it if it belongs to other instance of your class
}
public void testProtectedStatic() {
MyClass1 otherMC1 = new MyClass1();
MyClass2 otherMC2 = new MyClass2();
String testProtectedStatic;
testProtectedStatic = this.protectedStaticString; // OK - syntax trick
testProtectedStatic = super.protectedStaticString; // OK - syntax trick
testProtectedStatic = otherMC1.protectedStaticString; // OK - syntax trick
testProtectedStatic = otherMC2.protectedStaticString; // OK - syntax trick
testProtectedStatic = MyClass1.protectedStaticString; // OK - you can access protected static members from superclass
testProtectedStatic = MyClass2.protectedStaticString; // OK - this also static member of your class
}
}
Now, what is 'syntax trick'. Compiler allows you accessing static members like they were instance members:
MyClass mc = new MyClass();
Object o = mc.STATIC_FIELD;
But what will be actually compiled to the bytecode:
MyClass mc = new MyClass();
Object o = MyClass.STATIC_FIELD;
Accessing static members in this way is considered as bad practice because it's misleading. You should always access static members in a static way to avoid confusion while reading code.
This is what's goin on in your case. There were static field accessed in a non-static way, so it looked like instance field. When you removed static modifier, it became an instance member. The way this field is accessed changed, but you didn't notice that because of your object.staticField syntax.
Upvotes: 3
Reputation: 11486
Here is an interesting rule: You can access protected instance variables defined in a superclass, but you cannot access private instance variables in a subclass of that class with the private instance variables. e.g.
public class Super {
private String str;
}
public class Sub extends Super {
public void getStr(){
return str; // not allowed.
}
}
However, if the following was used, then this is allowed:
public class Super {
protected String str;
}
public class Sub extends Super {
public void getStr(){
return str; // allowed.
}
}
Upvotes: 0
Reputation: 4878
public
means it's visible to all classes.protected
means it's visible to the package and all sub-classes.private
means it's only visible in its own class.See Controlling Access to Members of a Class for more info.
Upvotes: 0
Reputation: 7476
As pointed out, static has nothing to do with visibility.
In your case, 'str' is marked as protected, which means that 2 types of classes can see it : - classes in the same package - classes that extend MyClass1
Your code works because MyClass2 extends MyClass1.
Upvotes: 1
Reputation: 7236
It has nothing to do with it being static or not. you can access the member because MyClass2 extends MyClass1
Upvotes: 0