Community
Participate
Working Groups
Build Identifier: 20091217-0918 Hi, we have a class that doesn't compile with the eclipse compiler. However, when using the standard Java compiler, it works without a problem. I'll attach an example of such a class that Eclipse cannot compile. Reproducible: Always
Created attachment 172418 [details] Example java file
Forgot to mention, the compilation error is: "The method min(Integer, Integer[]) is ambiguous for the type Tools" We also have this problem with Eclipse 3.5.2 and 3.6RC4
Will follow up, but it is worth noting that JDK7 (b91) refuses to compile this code with a complaint about reference to min being ambigious.
See that this also refuses to compile with javac 5. See bug 303814 comment 3 which applies to this case as well, but for wording specific to the test case there. *** This bug has been marked as a duplicate of bug 303814 ***
Please note there is a difference with bug 303814. The attached example to this bug does compile with a SUN javac 6, while the example with bug 303814 doesn't.
(In reply to comment #5) > Please note there is a difference with bug 303814. > The attached example to this bug does compile with a SUN javac 6, while the > example with bug 303814 doesn't. I believe that is due to a bug in javac 6 which has since been fixed in JDK7. We have seen many instances where javac fixes the defect only in JDK7 stream and not back port it to JDK6. Per earlier comment, this code also does not compile with javac 5. Our goal is not to be bug compatible with javac and so there is not much anything we can do here.
(In reply to comment #5) > Please note there is a difference with bug 303814. > The attached example to this bug does compile with a SUN javac 6, while the > example with bug 303814 doesn't. Hello Maarten, See that the slightly modified program below fails to compile on all flavors: javac 5,6,7 with the same error message as eclipse produces. The current test case hard codes the Integer type which in your case was inferred. Other than that there are no differences. public class Tools { public static void main(String[] args) { min(1, new Integer(5), new Integer(8)); } public static Integer min(Integer o1, Integer... o2) { return null; } public static Integer min(int extremum, Integer o1, Integer... o2) { return null; } } On your original test case, the javac7 vintage compiler has been reporting errors since build b25 dated: 04/10/08. So I propose to close the current bug as INVALID.
I've read your comment in the other bug report and read the JSL 3.0 trying to understand why it should throw this ambiguous error. If I understand correctly, this error is thrown because the first parameter of type 'int' is not a subtype of the first parameter of the other method, which is 'Integer' (cfr 15.12.2.5). So the following compiles because all parameters of the first method (String) are subtypes of the parameters of the second method (Object): public class Tools { public static void main(String[] args) { min("a", "b", "c"); } public static void min(String a, String b, String... c) {} public static void min(Object a, Object... b) {} } However, there must be something wrong with this reasoning because the following doesn't compile (with eclipse or javac), even though String is a subtype of Comparable: public class Tools { public static void main(String[] args) { min("a", "b", "c"); } public static void min(Comparable a, Comparable b, Comparable... c) {} public static void min(Object a, Object... b) {} } In addition, if both methods have the same type of arguments, it compiles again: public class Tools { public static void main(String[] args) { min("a", "b", "c"); } public static void min(Comparable a, Comparable... b) {} public static void min(Object a, Object... b) {} } This makes me suspect there is something wrong with my reasoning that it should compile if all parameters of the first method are subtypes of the parameters of the second method. So could you please explain why this shouldn't compile according to the JSL? thanks, Maarten
(In reply to comment #8) > I've read your comment in the other bug report and read the JSL 3.0 trying to > understand why it should throw this ambiguous error. > If I understand correctly, this error is thrown because the first parameter of > type 'int' is not a subtype of the first parameter of the other method, which > is 'Integer' (cfr 15.12.2.5). As I noted in comment#4, there is some wording in the other bug that is specific to the code fragment there. This argument of subtype or not was used to show why neither method is "more specific" than the other. Please see below: > So the following compiles because all parameters of the first method (String) > are subtypes of the parameters of the second method (Object): > > public class Tools { > public static void main(String[] args) { > min("a", "b", "c"); > } > public static void min(String a, String b, String... c) {} > public static void min(Object a, Object... b) {} > } By 15.12.2.5 (... The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error...) min(String a, String b, String... c) is more specific than min(Object a, Object... b) since any invocation handled by the former can be passed onto the latter. The reverse is not true since some invocations handled by min(Object a, Object... b) cannot be handled by min(String a, String b, String... c). For example, the call min (new Object(), new Object()); cannot be handled by the String version. So, min(String, String, String ...) is "strictly more specific" and also "maximally" specific for the invocation. Since there is only one method that is maximally specific, that method is also the "most specific method" and so the call is not ambiguous and to binds to the most specific method (min(String, String, String ...) This explains why the case above compiles alright. > However, there must be something wrong with this reasoning because the > following doesn't compile (with eclipse or javac), even though String is a > subtype of Comparable: > > public class Tools { > public static void main(String[] args) { > min("a", "b", "c"); > } > public static void min(Comparable a, Comparable b, Comparable... c) {} > public static void min(Object a, Object... b) {} > } The above is a perfectly valid program that compiles fine with eclipse as well as javac5,6,7. You can follow the same reasoning as above to show that min(Comparable a, Comparable b, Comparable... c) is maximally specific and so is the most specific method for the call you have. > In addition, if both methods have the same type of arguments, it compiles > again: No surprise here.
Here is categorical proof that this is a javac bug and the call is indeed ambiguous: Returning to your original test case: public class Tools { public static void main(String[] args) { min(1, new Integer(5), new Integer(8)); } public static <C extends Comparable<? super C>> C min(C o1, C... o2) { return null; } public static <C extends Comparable<? super C>> C min(int extremum, C o1, C... o2) { return null; } } The call min(1, new Integer(5), new Integer(8)) is ambiguous because both of the methods could satisfy the invocation and neither is more specific than the other and they are not override equivalent. Proof that neither is more specific than the other: (1) the call to min(new Integer(5)); if inserted in main() above could be bound to C min(C o1, C... o2) and cannot be bound to min(int extremum, C o1, C... o2); so C min(C o1, C... o2) is NOT more specific than min(int extremum, C o1, C... o2); (2) The call to min(10, 10, new Integer [] { 10 }); if inserted in main above, can only be serviced by min(int extremum, C o1, C... o2); and never by C min(C o1, C... o2). So min(int extremum, C o1, C... o2) is NOT more specific than C min(C o1, C... o2) (3) Since neither method is more specific, neither is strictly more specific and BOTH ARE maximally specific. (4) Since the method involved are not override equivalent, the method call is ambiguous. I could have perhaps helped your case by establishing this case earlier rather than pointing to duplicate which is very very similar, but not identical. So rather than close this as duplicate, I'll close this as INVALID this time.
Set wrong resolution by mistake, resetting to INVALID.
Verified for 3.7M1.