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

ECJ accepts instanceof check on parameterized non-static inner class in Java 17+ while javac rejects

Open
#4,356 2 comments 0 reactions 1 assignee Claimed by @srikanth-sankaran View on GitHub
Dominant language
Java
Stars
237
Forks
195
Avg merge
1d 12h
Merged PRs (30d)
47

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 1.8.0_461
javac 11.0.28
javac 17.0.16
javac 21.0.8
```

## Description:
When compiling the provided Java code, ECJ and javac exhibit divergent behavior regarding an instanceof check on a parameterized non-static inner class (`IteratorImpl`).

- Under Java 17 and Java 21, ECJ accepts the code with only a warning about type parameter shadowing.
- However, javac consistently rejects the code across all versions (including 17 and 21), reporting a compile-time error due to unsafe casting and an invalid instanceof check.
- Notably, ECJ itself rejects the same code under `-8` or `-11`, also issuing an error.

## Test program:
```java
public class Test {
}

class MyInteger {
}

interface Iterator {

boolean compare(Iterator other);
}

class TemplateClass {
public TemplateClass() {
}

public Iterator createIterator() {
return new IteratorImpl<>();
}

private class IteratorImpl implements Iterator {

private int currentIndex;

public IteratorImpl() {
this.currentIndex = 0;
}

@Override
public boolean compare(Iterator other) {
if (other instanceof IteratorImpl) {
IteratorImpl otherImpl = (IteratorImpl) other;
return this.currentIndex == otherImpl.currentIndex;
}
return false;
}
}
}

```

1. Using javac in 8, 11, 17 and 21, will have an error:
```bash
javac Test.java
```
```bash
Test.java:31: error: illegal generic type for instanceof
if (other instanceof IteratorImpl) {
^
Test.java:32: warning: [unchecked] unchecked cast
IteratorImpl otherImpl = (IteratorImpl) other;
^
required: TemplateClass.IteratorImpl
found: Iterator
where T#1,T#2 are type-variables:
T#1 extends Object declared in class TemplateClass.IteratorImpl
T#2 extends Object declared in class TemplateClass
1 error
1 warning
```

2. ECJ with `-17` or `-21` only have a warning:
```bash
java -jar ecj-4.37M3.jar -21 Test.java
```
```bash
----------
1. WARNING in Test.java (at line 21)
private class IteratorImpl implements Iterator {
^
The type parameter T is hiding the type T
----------
1 problem (1 warning)
```

3. However, ecj with `-8` or `-11` also will fail with following error message:
```bash
java -jar ecj-4.37M3.jar -11 Test.java
```
```bash
----------
1. WARNING in Test.java (at line 21)
private class IteratorImpl implements Iterator {
^
The type parameter T is hiding the type T
----------
2. ERROR in Test.java (at line 31)
if (other instanceof IteratorImpl) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Cannot perform instanceof check against parameterized type TemplateClass.IteratorImpl. Use the form TemplateClass.IteratorImpl instead since further generic type information will be erased at runtime
----------
2 problems (1 error, 1 warning)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.