-
Bug
-
Resolution: Fixed
-
P4
-
5.0, 6u10
-
b48
-
generic, x86
-
generic, linux
-
Verified
This program should not compile:
class Test<X extends Integer & Runnable> {
private X x = null;
public X getX() { return x; }
public static <T extends Integer & Runnable> Test<T> factory() { return new Test<T>(); }
public String toString() { return "Test("+x+")"; }
public static void main(String[] args) {
Test<?> t = Test.factory();
Integer i = t.getX();
Runnable r = t.getX();
System.out.println("Peter won't be happy: "+t);
}
}
The call to Test.factory should infer Object for T
and thus fail. Object is not a subtype of Integer nor
Runnable.
However I discovered that javac is really sensitive to little differences in the source code; consider the following source:
class Test<V> {
<T extends Integer & Runnable> Test<T> m() {
return null;
}
void test() {
Test<?> c1 = m(); //1 - should compile
Test<? extends String> c2 = m(); //2 - shouldn't compile
Test<? super String> c3 = m(); //3 - shoudln't compile
}
}
Surprisingly, javac rejects (1), which is wrong and, worse, diagnostics for both (2) and (3) reveal that something weird is going on:
Test3.java:6: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<?>
Test<?> c1 = m();
^
Test3.java:7: incompatible types; inferred type argument(s) java.lang.String do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<? extends java.lang.String>
Test<? extends String> c2 = m(); //2 - shoudln't compile
^
Test3.java:8: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<? super java.lang.String>
Test<? super String> c3 = m(); //3 - shoudln't compile
^
3 errors
The inferred types are all wrong:
(1) Object instead of Integer&Runnable
(2) String instead of error (glb(String,Integer,Runnable)
(3) Object instead of Integer&Runnable
class Test<X extends Integer & Runnable> {
private X x = null;
public X getX() { return x; }
public static <T extends Integer & Runnable> Test<T> factory() { return new Test<T>(); }
public String toString() { return "Test("+x+")"; }
public static void main(String[] args) {
Test<?> t = Test.factory();
Integer i = t.getX();
Runnable r = t.getX();
System.out.println("Peter won't be happy: "+t);
}
}
The call to Test.factory should infer Object for T
and thus fail. Object is not a subtype of Integer nor
Runnable.
However I discovered that javac is really sensitive to little differences in the source code; consider the following source:
class Test<V> {
<T extends Integer & Runnable> Test<T> m() {
return null;
}
void test() {
Test<?> c1 = m(); //1 - should compile
Test<? extends String> c2 = m(); //2 - shouldn't compile
Test<? super String> c3 = m(); //3 - shoudln't compile
}
}
Surprisingly, javac rejects (1), which is wrong and, worse, diagnostics for both (2) and (3) reveal that something weird is going on:
Test3.java:6: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<?>
Test<?> c1 = m();
^
Test3.java:7: incompatible types; inferred type argument(s) java.lang.String do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<? extends java.lang.String>
Test<? extends String> c2 = m(); //2 - shoudln't compile
^
Test3.java:8: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T
found : <T>Test<T>
required: Test<? super java.lang.String>
Test<? super String> c3 = m(); //3 - shoudln't compile
^
3 errors
The inferred types are all wrong:
(1) Object instead of Integer&Runnable
(2) String instead of error (glb(String,Integer,Runnable)
(3) Object instead of Integer&Runnable
- duplicates
-
JDK-6971909 A type inference with assignment conversion (JLS 15.12.2.8) fails
- Closed
- relates to
-
JDK-6785112 Umbrella: issues with generic method type-inference
- Closed
-
JDK-6835428 regression: return-type inference rejects valid code
- Closed