-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 4.8.15-1-MANJARO #1 SMP PREEMPT Thu Dec 15 22:22:45 UTC 2016 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
A method is called by passing a lambda expression as single argument. That method is overloaded. The first method takes a java.util.function.Supplier<?> as single argument, the second one expects <T extends java.lang.Number>.
The compiler fails saying that also the second method matches the method reference.
Interestingly, the code does compile when changing <T extends java.lang.Number> to java.lang.Number.
This is probably related to the problem already reported inJDK-8164611, but I wasn't sure if it's exactly the same issue.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the code via "javac AmbiguousReferenceTest.java".
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I'd expected the code to compile and print "success" when run via "java AmbiguousReferenceTest".
ACTUAL -
The code didn't compile (ambiguous reference).
It does compile on Eclipse though and the test prints "success" (as expected).
Eclipse IDE for Java Developers
Version: Neon.2 Release (4.6.2)
Build id: 20161208-0600
ERROR MESSAGES/STACK TRACES THAT OCCUR :
AmbiguousReferenceTest.java:5: error: reference to test is ambiguous
test(() -> true);
^
both method test(Supplier<Boolean>) in AmbiguousReferenceTest and method <T>test(T) in AmbiguousReferenceTest match
where T is a type-variable:
T extends Number declared in method <T>test(T)
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class AmbiguousReferenceTest {
public static void main(String[] args) {
test((java.util.function.Supplier<?>) (() -> true));
test(() -> true);
System.out.println("success");
}
static void test(java.util.function.Supplier<?> obj) {
// fine
}
// with this method the class compiles
// static void test(java.lang.Number obj) {
// throw new AssertionError("shouldn't be called");
// }
// with this method the class doesn't compile
static <T extends java.lang.Number> void test(T obj) {
throw new AssertionError("shouldn't be called");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Workaround 1: don't use generics in the second method (i.e. the one that shouldn't be called). See commented out lines 14-16.
Workaround 2: cast the argument when calling the method. See line 4.
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 4.8.15-1-MANJARO #1 SMP PREEMPT Thu Dec 15 22:22:45 UTC 2016 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
A method is called by passing a lambda expression as single argument. That method is overloaded. The first method takes a java.util.function.Supplier<?> as single argument, the second one expects <T extends java.lang.Number>.
The compiler fails saying that also the second method matches the method reference.
Interestingly, the code does compile when changing <T extends java.lang.Number> to java.lang.Number.
This is probably related to the problem already reported in
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the code via "javac AmbiguousReferenceTest.java".
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I'd expected the code to compile and print "success" when run via "java AmbiguousReferenceTest".
ACTUAL -
The code didn't compile (ambiguous reference).
It does compile on Eclipse though and the test prints "success" (as expected).
Eclipse IDE for Java Developers
Version: Neon.2 Release (4.6.2)
Build id: 20161208-0600
ERROR MESSAGES/STACK TRACES THAT OCCUR :
AmbiguousReferenceTest.java:5: error: reference to test is ambiguous
test(() -> true);
^
both method test(Supplier<Boolean>) in AmbiguousReferenceTest and method <T>test(T) in AmbiguousReferenceTest match
where T is a type-variable:
T extends Number declared in method <T>test(T)
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class AmbiguousReferenceTest {
public static void main(String[] args) {
test((java.util.function.Supplier<?>) (() -> true));
test(() -> true);
System.out.println("success");
}
static void test(java.util.function.Supplier<?> obj) {
// fine
}
// with this method the class compiles
// static void test(java.lang.Number obj) {
// throw new AssertionError("shouldn't be called");
// }
// with this method the class doesn't compile
static <T extends java.lang.Number> void test(T obj) {
throw new AssertionError("shouldn't be called");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Workaround 1: don't use generics in the second method (i.e. the one that shouldn't be called). See commented out lines 14-16.
Workaround 2: cast the argument when calling the method. See line 4.
- duplicates
-
JDK-8164611 Type inference problem. Ambiguous method
-
- Closed
-