-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
8
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
javac 1.8.0_461
java version "1.8.0_461"
Java(TM) SE Runtime Environment (build 1.8.0_461-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.461-b11, mixed mode)
A DESCRIPTION OF THE PROBLEM :
There is a significant behavioral inconsistency in javac's handling of generic constructor type inference across major JDK versions when used in conjunction with Enum.valueOf and target typing.
The following valid Java code compiles successfully with warnings only in JDK 11, 17, and 21, but is rejected with a compilation error in JDK 8.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compling following code using javac in JDK8.
```
javac Test.java
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compliation should succeed with similar note in JDK11, 17 and 21:
```
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
```
ACTUAL -
The compliation fail and report following error message:
```
Test.java:25: error: cannot infer type arguments for EnumWrapper<>
EnumWrapper<T> nextWrapper = new EnumWrapper<>(T.valueOf(wrapper.getValue().getClass(), wrapper.getValue().name()));
^
reason: inference variable T#1 has incompatible bounds
equality constraints: T#2,CAP#1
lower bounds: Enum,CAP#1
where T#1,T#2 are type-variables:
T#1 extends Enum<T#1> declared in method <T#1>valueOf(Class<T#1>,String)
T#2 extends Enum<T#2> declared in class EnumWrapper
where CAP#1 is a fresh type-variable:
CAP#1 extends Enum from capture of ? extends Enum
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
```
---------- BEGIN SOURCE ----------
public class Test {
}
enum Color {
RED, GREEN, BLUE
}
class EnumWrapper<T extends Enum<T>> {
private T value;
public EnumWrapper(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
class RecursiveTemplate<T extends Enum<T>> {
public void process(EnumWrapper<T> wrapper, int depth) {
if (depth <= 0)
return;
EnumWrapper<T> nextWrapper = new EnumWrapper<>(T.valueOf(wrapper.getValue().getClass(), wrapper.getValue().name()));
process(nextWrapper, depth - 1);
}
}
---------- END SOURCE ----------
javac 1.8.0_461
java version "1.8.0_461"
Java(TM) SE Runtime Environment (build 1.8.0_461-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.461-b11, mixed mode)
A DESCRIPTION OF THE PROBLEM :
There is a significant behavioral inconsistency in javac's handling of generic constructor type inference across major JDK versions when used in conjunction with Enum.valueOf and target typing.
The following valid Java code compiles successfully with warnings only in JDK 11, 17, and 21, but is rejected with a compilation error in JDK 8.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compling following code using javac in JDK8.
```
javac Test.java
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compliation should succeed with similar note in JDK11, 17 and 21:
```
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
```
ACTUAL -
The compliation fail and report following error message:
```
Test.java:25: error: cannot infer type arguments for EnumWrapper<>
EnumWrapper<T> nextWrapper = new EnumWrapper<>(T.valueOf(wrapper.getValue().getClass(), wrapper.getValue().name()));
^
reason: inference variable T#1 has incompatible bounds
equality constraints: T#2,CAP#1
lower bounds: Enum,CAP#1
where T#1,T#2 are type-variables:
T#1 extends Enum<T#1> declared in method <T#1>valueOf(Class<T#1>,String)
T#2 extends Enum<T#2> declared in class EnumWrapper
where CAP#1 is a fresh type-variable:
CAP#1 extends Enum from capture of ? extends Enum
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
```
---------- BEGIN SOURCE ----------
public class Test {
}
enum Color {
RED, GREEN, BLUE
}
class EnumWrapper<T extends Enum<T>> {
private T value;
public EnumWrapper(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
class RecursiveTemplate<T extends Enum<T>> {
public void process(EnumWrapper<T> wrapper, int depth) {
if (depth <= 0)
return;
EnumWrapper<T> nextWrapper = new EnumWrapper<>(T.valueOf(wrapper.getValue().getClass(), wrapper.getValue().name()));
process(nextWrapper, depth - 1);
}
}
---------- END SOURCE ----------