Summary: | Subtle visibility problem: class declaration resolved improperly | ||
---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Radek Szklarczyk <radek_szklarczyk> |
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> |
Status: | RESOLVED WONTFIX | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | ||
Version: | 2.0 | ||
Target Milestone: | 2.1 M1 | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: |
Description
Radek Szklarczyk
2002-08-26 06:04:44 EDT
I tried the following example: package a; public class A { protected int return0() { return -1; } } package a.b; public class B extends a.A { protected int return0() { return 0; } } package a; import a.b.B; public class C { public static void main(String[] args) { System.out.println(new B().return0()); } } I compiled with javac and ran a.C.main()... the result is 0 as expected. But if you rename A.return0() to return1() then a.C fails to compile because: a/C.java:5: return0() has protected access in a.b.B System.out.println(new B().return0()); Our understanding (backed up by all the test suites) is that protected fields/methods are not visible at compile time outside their package unless the type is a subclass. Radek: Do you agree? I'm not sure whether I can agree. As you can see in your example protected method a.b.B.return0() IS visible from a.C, but the method is neither in the same package as C nor C is "subclass related" to B. And in this case, unlike Java lang spec, Java VM spec is very clear on this: the method is visible. That came to me as surprise as well. My point is: pressing F3 on the invocation of a.b.B.return0() from a.C.main should lead to the correct method, not a.A.return0() as it does now. Sorry I guess I wasn't clear enough... the protected method B.return0() is not visible at compile time (as you can see when A.return0() does not exist) but is visible to the VM at execution time if it overrides a visible method (A.return0 ()). F3 shows the method that the compiler found, not the method which is found by the VM. Kent is right, there is a subtle difference in between compile/runtime protected checks (by the spec) and our behavior is the proper one. The compiler static check is fine. Though I understand this behavior to be counter intuitive, but this is enforced by the Java language spec. Closing |