Community
Participate
Working Groups
The built-in Java compiler has problems with method visibility with the following code: In a package called packageA there exists an interface definition and class definition as such: public interface InterfaceA { public String doSomething(); } public class TypeA implements InterfaceA { public String doSomething() { return "Something"; } protected String mySomething() { return "foo"; } } In packageB, we have the following class: import packageA.InterfaceA; import packageA.TypeA; public class TypeB extends TypeA { protected String doSomethingWithSomething(InterfaceA anA) { return ((TypeA) anA).mySomething(); } } The Eclipse Java compiler complains that the method "mySomething()" is not visible. The auto correct feature suggests making TypeA.mySomething() protected. Of course, it already is a protected method. The Java compiler provided with JDK 1.4.1_02 does not report any compiler errors with this code.
I just tried this example with jdk 1.4.1 & it reports the same error we do. D:\temp>javac p2/B.java p2/B.java:8: mySomething() has protected access in p1.A return ((A ) anA).mySomething(); ^ 1 error
Yup, you are correct that JDK 1.4.1_02 does report an error. However, I still fail to see why it is an error. The method being invoked is marked as 'protected' which should mean that it is visible to items in the package as well as to subclasses in any package. I'm casting the parameter which comes in as an 'InterfaceA' to be a 'TypeA'. An instance of TypeA clearly has access to this method. If I move TypeB to the same package as TypeA, the compiler doesn't object. I fail to see why it should matter what package TypeB resides in, particularly when it isn't an instance of TypeB which is calling the method in question. Even if it was, the method should be visible because TypeB is a subclass of TypeA.
This behavior is described in the JLS 6.6.2 (also check example in 6.6.7). Basically protected methods can be used in subclasses TypeB on receivers of type TypeB (or subtype), not on supertype TypeA. So: 'this.mySomething()' would be allowed.