FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
OS should not matter, but this was tested on Ubuntu 14.04 32 bit,
A DESCRIPTION OF THE PROBLEM :
Information about whether a type has a wildcard upper bound seems to get lost for programs which contain a certain combination of generic methods. The result is that incorrect programs type check without warnings, which might lead to heap pollution and unexpected ClassCastExceptions.
I have tried this with Eclipse 4.5.2 (realeased version) and Eclipse 4.6 (Build id: I20160525-2000). JDK 1.8.0_77 also has the same behaviour.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the example program from the description section.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compilation should fail with a compilation error, for example:
LostWildCardCompilerBug.java:58: error: incompatible types: inference variable T has incompatible bounds
Set<List<Number>> numbetListSet1 = Collections.singleton(toWildcardGeneric(integerList));
^
equality constraints: List<Number>
lower bounds: List<CAP#1>
where T is a type-variable:
T extends Object declared in method <T>singleton(T)
where CAP#1 is a fresh type-variable:
CAP#1 extends Integer from capture of ? extends Integer
1 error
ACTUAL -
The program compiles without warnings. When run it crashes the a ClassCastException and gives the following output:
Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
at LostWildCardCompilerBug.main(LostWildCardCompilerBug.java:50)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
class JavacLostWildCardCompilerBug {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
// This assignment should not be allowed
Set<List<Number>> numbetListSet = Collections.singleton(toWildcardGeneric(integerList));
numbetListSet.iterator().next().add(new Float(1.0));
Integer i = integerList.get(0); // Throws ClassCastException
}
static <T> List<? extends T> toWildcardGeneric(List<T> l) {
return l;
}
}
---------- END SOURCE ----------
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
OS should not matter, but this was tested on Ubuntu 14.04 32 bit,
A DESCRIPTION OF THE PROBLEM :
Information about whether a type has a wildcard upper bound seems to get lost for programs which contain a certain combination of generic methods. The result is that incorrect programs type check without warnings, which might lead to heap pollution and unexpected ClassCastExceptions.
I have tried this with Eclipse 4.5.2 (realeased version) and Eclipse 4.6 (Build id: I20160525-2000). JDK 1.8.0_77 also has the same behaviour.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the example program from the description section.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compilation should fail with a compilation error, for example:
LostWildCardCompilerBug.java:58: error: incompatible types: inference variable T has incompatible bounds
Set<List<Number>> numbetListSet1 = Collections.singleton(toWildcardGeneric(integerList));
^
equality constraints: List<Number>
lower bounds: List<CAP#1>
where T is a type-variable:
T extends Object declared in method <T>singleton(T)
where CAP#1 is a fresh type-variable:
CAP#1 extends Integer from capture of ? extends Integer
1 error
ACTUAL -
The program compiles without warnings. When run it crashes the a ClassCastException and gives the following output:
Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
at LostWildCardCompilerBug.main(LostWildCardCompilerBug.java:50)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
class JavacLostWildCardCompilerBug {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
// This assignment should not be allowed
Set<List<Number>> numbetListSet = Collections.singleton(toWildcardGeneric(integerList));
numbetListSet.iterator().next().add(new Float(1.0));
Integer i = integerList.get(0); // Throws ClassCastException
}
static <T> List<? extends T> toWildcardGeneric(List<T> l) {
return l;
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8067767 type inference performance regression
-
- Closed
-