eclipse-jdt / eclipse-jdt/eclipse.jdt.core
ECJ and javac differ in handling incompatible List to ArrayList generic type conversion
- Dominant language
- Java
- Stars
- 237
- Forks
- 195
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 49
Description
## ECJ Version:
```bash
Eclipse Compiler for Java(TM) v20250814-1944, 3.43.0, Copyright IBM Corp 2000, 2020. All rights reserved.
```
## Javac Version:
```bash
javac 21.0.8
```
## Description:
When compiling the following Java code, ECJ and javac exhibit different behaviors regarding an incompatible type conversion in a generic context. ECJ only issues warnings about "Type safety" violations, while javac rejects the code with a compilation error.
This difference in behavior raises questions about which compiler is correctly following the Java Language Specification regarding type safety enforcement in generic type conversions. Thanks for your insight.
## Test program:
```java
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
public class Test {
public static void main(final String[] args) {
C t = new C(2);
}
}
interface A {
}
class B implements A {
}
class C> {
private T[] array;
public C(int size) {
this.array = (T[]) Array.newInstance((Class) ((ArrayList) Collections.emptyList()).get(0).getClass(), size);
}
}
```
Using javac it will have an error:
```bash
javac Test.java
```
```bash
Test.java:21: error: incompatible types: List cannot be converted to ArrayList
this.array = (T[]) Array.newInstance((Class) ((ArrayList) Collections.emptyList()).get(0).getClass(), size);
^
where T is a type-variable:
T extends A declared in class C
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
```
However, ecj only have some warnings:
```bash
java -jar ecj-4.37M3.jar -21 Test.java
```
```bash
----------
1. WARNING in Test.java (at line 7)
C t = new C(2);
^
The value of the local variable t is not used
----------
2. WARNING in Test.java (at line 7)
C t = new C(2);
^^^^^^^^
Type safety: The expression of type C needs unchecked conversion to conform to C
----------
3. WARNING in Test.java (at line 7)
C t = new C(2);
^
C is a raw type. References to generic type C should be parameterized
----------
4. WARNING in Test.java (at line 18)
private T[] array;
^^^^^
The value of the field C.array is not used
----------
5. WARNING in Test.java (at line 21)
this.array = (T[]) Array.newInstance((Class) ((ArrayList) Collections.emptyList()).get(0).getClass(), size);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Type safety: Unchecked cast from Object to T[]
----------
6. WARNING in Test.java (at line 21)
this.array = (T[]) Array.newInstance((Class) ((ArrayList) Collections.emptyList()).get(0).getClass(), size);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Type safety: Unchecked cast from Class to Class
----------
7. WARNING in Test.java (at line 21)
this.array = (T[]) Array.newInstance((Class) ((ArrayList) Collections.emptyList()).get(0).getClass(), size);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Type safety: Unchecked cast from List to ArrayList
----------
7 problems (7 warnings)
```
Contributor guide
Research direction
Start with the Test.java reproducer and run the supplied javac and ECJ commands to confirm the differing diagnostics. Trace ECJ’s generic cast and type-conversion handling against the applicable Java Language Specification rules; done means the compiler behavior is resolved and covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100