Bug 22830 - Subtle visibility problem: class declaration resolved improperly
Summary: Subtle visibility problem: class declaration resolved improperly
Status: RESOLVED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: 2.1 M1   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-08-26 06:04 EDT by Radek Szklarczyk CLA
Modified: 2002-09-10 08:51 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Radek Szklarczyk CLA 2002-08-26 06:04:44 EDT
Let's consider an example:

package junit.jxelink.devirtualization;
public class BT_Method {
	protected int return0() {
		return -1;
	}
}

package junit.jxelink.devirtualization.addon;
public class ScMethod extends BT_Method {
	protected int return0() {
		return 0;
	}
}

package junit.jxelink.devirtualization;
public class BT_Class {
	public int return0() {
		return new ScMethod().return0();
	}
}

When one puts the cursor on "return0()" method invocation in BT_Class and
presses F3 the decalaration is resolved as BT_Method.return0, which is wrong.
Apparently JDT thinks that ScMethod.return0 isn't accessible, but it is,
according to Java Lang Spec ver.2; section 6.6.2.1 "Access to a protected Member"
Comment 1 Kent Johnson CLA 2002-09-04 15:15:50 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?
Comment 2 Radek Szklarczyk CLA 2002-09-05 11:09:36 EDT
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.
Comment 3 Kent Johnson CLA 2002-09-05 12:07:34 EDT
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.
Comment 4 Philipe Mulet CLA 2002-09-09 05:46:34 EDT
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