FULL PRODUCT VERSION :
javac 1.6.0_20
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01-279, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mini 2.6.32-gentoo-r7 #2 SMP Sat Jun 26 10:59:21 JST 2010 i686 Intel(R) Core(TM)2 Duo CPU E8235 @ 2.80GHz GenuineIntel GNU/Linux
Windows XP SP3 (Sun JDK 1.6.0_20)
Mac OS X 10.6.4 (Apple JDK 1.6.0_20)
A DESCRIPTION OF THE PROBLEM :
When compiling the attached source, compiler cannot infer the type variable T in the case map4:
<T> Map<T, T> createMap() {return null;}
...
Map<? super Integer, Integer> map4 = createMap();
However, compiler can infer the type variable in the case map1:
Map<Integer, ? super Integer> map1 = createMap();
When I specify the type argument explicitly, comple success:
Map<? super Integer, Integer> map2 = this.<Integer>createMap();
Moreover, replacing keyword 'super' with 'extends' also make compile success:
Map<? extends Integer, Integer> map3 = createMap();
Accordding to the type inference algorithm specified in JLS 15.12.2.7 and 15.12.2.8, type inference must success as follows:
1. Since there is no arguments, no type variables are infered.
2. Since the return value is assigned to a variable, the type of the variable is taken into account.
2.1. The type S in JLS 15.12.2.8 is Map<? super Integer, Integer>, and R and R' is Map<T, T>.
2.2. The constraint Map<? super Integer, Integer> >> Map<T, T> is added to the constraint set.
3. Now, we will back to the type inference algorithm at 15.12.2.7. The constraint Map<? super Integer, Integer> >> Map<T, T> is decomposed to Integer << T and Integer = T.
4. The constraint Integer << T is converted to T :> Integer, and Integer = T is converted T = Integer.
5. Since equality constraints are resolved first, the constraint T = Integer is resolved with substitution T |-> Integer (in this bug report, U |-> V represents substitution of V for U).
6. The substitution T |-> Integer is applied to all remaining constraints, so that the constraint T :> Integer is now Integer :> Integer.
7. Since the relation :> is reflective (JLS 4.10), the constraint Integer :> Integer is satisfied.
8. Since all constraints are solved, the type inference algorithm ends successfully with a substitution T |-> Integer.
Additional notes:
The internal compiler of eclipse 3.5 can compile successfully.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile attached source: javac test.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compile without error. The type variable T is infered as a Integer.
ACTUAL -
Compiler cannot find instance of the type variable T, so that compile fails.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
test.java:15: incompatible types; no instance(s) of type variable(s) T exist so that java.util.Map<T,T> conforms to java.util.Map<? super java.lang.Integer,java.lang.Integer>
found : <T>java.util.Map<T,T>
required: java.util.Map<? super java.lang.Integer,java.lang.Integer>
Map<? super Integer, Integer> map4 = createMap();
^
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.*;
public class test {
public void foo() {
// OK
Map<Integer, ? super Integer> map1 = createMap();
// OK
Map<? super Integer, Integer> map2 = this.<Integer>createMap();
// OK
Map<? extends Integer, Integer> map3 = createMap();
// NG
Map<? super Integer, Integer> map4 = createMap();
}
public <T> Map<T, T> createMap() {
return null;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Specify the type arguments explicitly.
javac 1.6.0_20
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01-279, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mini 2.6.32-gentoo-r7 #2 SMP Sat Jun 26 10:59:21 JST 2010 i686 Intel(R) Core(TM)2 Duo CPU E8235 @ 2.80GHz GenuineIntel GNU/Linux
Windows XP SP3 (Sun JDK 1.6.0_20)
Mac OS X 10.6.4 (Apple JDK 1.6.0_20)
A DESCRIPTION OF THE PROBLEM :
When compiling the attached source, compiler cannot infer the type variable T in the case map4:
<T> Map<T, T> createMap() {return null;}
...
Map<? super Integer, Integer> map4 = createMap();
However, compiler can infer the type variable in the case map1:
Map<Integer, ? super Integer> map1 = createMap();
When I specify the type argument explicitly, comple success:
Map<? super Integer, Integer> map2 = this.<Integer>createMap();
Moreover, replacing keyword 'super' with 'extends' also make compile success:
Map<? extends Integer, Integer> map3 = createMap();
Accordding to the type inference algorithm specified in JLS 15.12.2.7 and 15.12.2.8, type inference must success as follows:
1. Since there is no arguments, no type variables are infered.
2. Since the return value is assigned to a variable, the type of the variable is taken into account.
2.1. The type S in JLS 15.12.2.8 is Map<? super Integer, Integer>, and R and R' is Map<T, T>.
2.2. The constraint Map<? super Integer, Integer> >> Map<T, T> is added to the constraint set.
3. Now, we will back to the type inference algorithm at 15.12.2.7. The constraint Map<? super Integer, Integer> >> Map<T, T> is decomposed to Integer << T and Integer = T.
4. The constraint Integer << T is converted to T :> Integer, and Integer = T is converted T = Integer.
5. Since equality constraints are resolved first, the constraint T = Integer is resolved with substitution T |-> Integer (in this bug report, U |-> V represents substitution of V for U).
6. The substitution T |-> Integer is applied to all remaining constraints, so that the constraint T :> Integer is now Integer :> Integer.
7. Since the relation :> is reflective (JLS 4.10), the constraint Integer :> Integer is satisfied.
8. Since all constraints are solved, the type inference algorithm ends successfully with a substitution T |-> Integer.
Additional notes:
The internal compiler of eclipse 3.5 can compile successfully.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile attached source: javac test.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compile without error. The type variable T is infered as a Integer.
ACTUAL -
Compiler cannot find instance of the type variable T, so that compile fails.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
test.java:15: incompatible types; no instance(s) of type variable(s) T exist so that java.util.Map<T,T> conforms to java.util.Map<? super java.lang.Integer,java.lang.Integer>
found : <T>java.util.Map<T,T>
required: java.util.Map<? super java.lang.Integer,java.lang.Integer>
Map<? super Integer, Integer> map4 = createMap();
^
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.*;
public class test {
public void foo() {
// OK
Map<Integer, ? super Integer> map1 = createMap();
// OK
Map<? super Integer, Integer> map2 = this.<Integer>createMap();
// OK
Map<? extends Integer, Integer> map3 = createMap();
// NG
Map<? super Integer, Integer> map4 = createMap();
}
public <T> Map<T, T> createMap() {
return null;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Specify the type arguments explicitly.
- duplicates
-
JDK-6315770 javac inference allows creation of strange types: Integer & Runnable
-
- Closed
-