Community
Participate
Working Groups
Using v_749, the following test case fails. package p1; import static p.C.s; public class X {} ---------------------- package p; interface I { String s = ""; } class B { public static String s = "Hello, World!"; } public class C extends B implements I {} -------------------- We report: ---------- 1. ERROR in D:\tests_sources\p1\X.java (at line 3) import static p.C.s; ^^^^^ The field s is ambiguous ---------- 1 problem (1 error) This worked with M6. javac (1.5/1.6/1.7) also compiles it fine.
Created attachment 64321 [details] Patch to fix the problem message Without this patch we report the error calling the field 'B' instead of 'i'
I remove the regression from the title since we failed with M5 and M6. So this is not a new problem.
We have the same issue with types. package p1; import static p.C.B; public class X {} --------------------- package p; interface I { class B {} } class D { public static class B {} } public class C extends D implements I {} In this case we report the import for B as being not visible. ---------- 1. ERROR in d:\tests_sources\p1\X.java (at line 3) import static p.C.B; ^^^^^ The type p.C.B is not visible ---------- Both cases are ok with javac.
Patch has been released to HEAD. Code coverage showed that this path was never used in the ProblemReporter.
In the case from comment 0, javac returns the field from I.
They complain when the type C implements 2 superinterfaces I & J that define the same field, but not a superclass & a superinterface? Sounds fishy to me.
Sounds buggy. We might want to check the specs carefully. I don't see how they see more one field than the other.
javac does complain when C implements 2 interfaces: package p; interface I { String s = ""; } interface J { String s = ""; } public class C implements I, J {} X.java:1: s is already defined in a static single-type import Need to verify that the spec indicates that superinterfaces have precedence over superclasses
Reopening - didn't mean to close
Section 8.3.3.3 describes the case of a type X inheriting a field from 2 interfaces or a superclass & superinterace. A simple reference to the field name within X in this case is reported as ambiguous. What's the difference with a static import reference to the field thru the type X? None that I can find, but then I cannot find any specific mention of a static import finding an inherited field.
From the original testcase in comment #0, if we add a reference to s in the type C : package p; interface I { String s = ""; } class B { public static String s = "Hello, World!"; } public class C extends B implements I { String myString = s; } javac reports an error since s is ambiguous. If its ambiguous inside C, it should also be ambiguous to the static import statement in X. Closing as Invalid
Verified for 3.3M7.
Adding some more details to this closed bug, in case this comes back to cause problems. If we have: Unit p1.M: package p1; interface I1 { int f = 1; } interface I2 { int f = 2; } class C { public static int f = 3; } class M extends C implements I1, I2 {} Unit p2.Q: package p2; import static p1.M.f; class Q { public static void main(String[] args) { System.out.println("f = " + f); } } javac will compile without complaints, and will output "f = 1". If the import order on M is changed to "class M extends C implements I2, I1", then it will output "f = 2". As Kent noted, if f is accessed within class M, javac will flag it as ambiguous. If the 'public' specifier is omitted from the definition of f on C, then Eclipse will still complain about f being ambiguous, and javac will complain that it can't find f at all: p2\Q.java:3: cannot find symbol symbol : static f location: class p1.M import static p1.M.f; ^ p2\Q.java:7: cannot find symbol symbol : variable f location: class p2.Q System.out.println("f equals " + f); ^ If I2 is removed, and the 'public' specifier is omitted from C.f, then Eclipse will compile and run (and output "f = 1"), but javac will still complain that it can't find f at all. Note that although adding 'public' to C.f lets javac compile, the value that is output is the value specified by I1.f (or I2.f if that is first in the interface list). So it seems to me like the javac behavior is pretty random, perhaps reflecting a poorly designed language feature, but looking through Sun's bug database it also seems like the spec has had plenty of argument already.
Actually, digging deeper, I am going to reopen this bug. Sorry if it is just my confusion. JLS section 7.5.3, "Single Static Import Declaration", says: "Note that it is permissable for one single-static-import declaration to import several fields or types with the same name, or several methods with the same name and signature." My reading is that the import statement itself is not considered ambiguous, although it may create a subsequent ambiguity when the field or type is referenced.
It indeed feels that the static import could be tolerated, though subsequent field references should be doomed...
Added StaticImportTest#test059-062
Created attachment 92861 [details] Proposed patch
Released for 3.4M6. Fixed
Now we differ on which field is chosen. For example, package p; import static q.A.a; public class X { public static void main(String[] s) { System.out.println(a); } } package q; public class A extends B implements J, I {} interface I { String a = "1"; } interface J { String a = "2"; } class B { public static String a = "3"; } I still find it difficult to understand how any of these 3 fields can be picked over the others. But we're not going to report an error, then we should probably pick the same field.
Reopening...
Created attachment 92938 [details] Proposed patch with testcase
The latest patch reports ambiguous errors against each use of an ambiguous field but leaves the import statement alone.
Released new patch into HEAD for 3.4M6
The latest change appears to have introduced a crashing bug (see bug 223253). Also, the case mentioned in comment 3 (which is the same case that causes the crash) still does not seem to be fixed, based on some testing with ecj.jar.
And as for this case: package p2; interface I { class B {} } class D { //public static class B {} //static class B {} } public class C extends D implements I {} ------------ package p1; import static p.C.B; public class X {} javac reports an error when D.B is not visible and I.B doesn't exist. So why is a non-visible member type from the class D an error, but a non-visible member type from the interface I is OK ? I'm not convinced we want to match this strange behaviour.
We're going to close this one again Walter. The above case is not one we want to match right now.
Created attachment 93065 [details] New proposed patch Now treat ambiguous member types and fields the same. Only report the ambiguous error on a reference & not the static import statement.
Latest version looks good. Thanks!
Verified for 3.4M6 using build I20080324-1300