eclipse-jdt / eclipse-jdt/eclipse.jdt.core

ECJ and javac differ in handling incompatible List to ArrayList generic type conversion

Open
#4,352 1 comment 0 reactions 0 assignees View on GitHub
rawtypes
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.