-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 8.1 Enterprise x64, version 6.3.9600
A DESCRIPTION OF THE PROBLEM :
The following code demonstrates a problem in subtyping relation between generic types with wildcard type arguments, as implemented in the javac. The code compiles successfully without any unchecked cast warnings, but causes a heap pollution that results in a ClassCastException in a position where no explicit cast is made.
```
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following code:
```
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A compile-time error expected:
Error:(9, 60) java: incompatible types: java.util.ArrayList<capture#1 of ? extends Matrix<?>> cannot be converted to java.util.ArrayList<? extends java.util.ArrayList<java.util.ArrayList<?>>>
ACTUAL -
No compile time errors. An exception occurs when the program is run:
Exception in thread "main" java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
at Matrix.main
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
at Matrix.main
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
---------- END SOURCE ----------
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 8.1 Enterprise x64, version 6.3.9600
A DESCRIPTION OF THE PROBLEM :
The following code demonstrates a problem in subtyping relation between generic types with wildcard type arguments, as implemented in the javac. The code compiles successfully without any unchecked cast warnings, but causes a heap pollution that results in a ClassCastException in a position where no explicit cast is made.
```
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following code:
```
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A compile-time error expected:
Error:(9, 60) java: incompatible types: java.util.ArrayList<capture#1 of ? extends Matrix<?>> cannot be converted to java.util.ArrayList<? extends java.util.ArrayList<java.util.ArrayList<?>>>
ACTUAL -
No compile time errors. An exception occurs when the program is run:
Exception in thread "main" java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
at Matrix.main
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
at Matrix.main
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
class Matrix<T> extends ArrayList<ArrayList<T>> {
public static void main(String[] args) {
Matrix<String> lorem = new Matrix<>();
ArrayList<Matrix<String>> ipsum = new ArrayList<>();
ipsum.add(lorem);
ArrayList<? extends Matrix<?>> dolor = ipsum;
ArrayList<? extends ArrayList<ArrayList<?>>> sit = dolor; // This assignment is not type-safe, but is accepted by javac
sit.get(0).add(sit);
String amet = lorem.get(0).get(0); // java.lang.ClassCastException: Matrix cannot be cast to java.lang.String
}
}
---------- END SOURCE ----------
- duplicates
-
JDK-8164401 Incorrect treatment of wildcards in subtyping
- Open