-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8-pool, 11, 17, 19, 20, 21
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
openjdk 21-ea 2023-09-19
OpenJDK Runtime Environment (build 21-ea+12-971)
OpenJDK 64-Bit Server VM (build 21-ea+12-971, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Given a generic method that is intended to be invoked, javac will accept the invocation if the code for the parameter is directly nested within the invocation, but not if this argument is extracted into a local variable first and then this variable is applied to the method. Specifically note the two classes (intended as two separate test cases) given. The test case corresponding to class Test1 puts the code for the first argument of test2 directly in the method invocation. The test case corresponding to class Test2 extracts the code for the first argument and first puts it in a local variable. Regardless of this seemingly irrelevant change in the code, the second test case no longer compiles. It is my opinion that the original code should have never been valid to begin with and should have been rejected by javac.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the code within class Test1 - this should be allowed. Now try to compile the code within class Test2 - this is not allowed.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
javac should be consistent in whether the method invocation is valid or not, even when the code for the method argument is extracted into a local variable. The consistent result should be that both code snippets fail since the result of asSubclass is of type Class<? extends Number>, hence type argument U gets the form of ? extends Number, whereas the original type is of T extends Number. The actual type described by these may not be the same, but this is mandated by the contract of method test2.
ACTUAL -
javac is inconsistent with regards to the applicability of the method invocation. If the argument is lifted to a local variable, the method invocation is no longer valid.
---------- BEGIN SOURCE ----------
public class Test1 {
private <T extends Number> void test(T y) throws ClassNotFoundException {
test2(Class.forName("x").asSubclass(Number.class), y);
}
private <U> void test2(Class<U> x, U y) {}
}
public class Test2 {
private <T extends Number> void test(T y) throws ClassNotFoundException {
var x = Class.forName("x").asSubclass(Number.class);
test2(x, y);
}
private <U> void test2(Class<U> x, U y) {}
}
---------- END SOURCE ----------
FREQUENCY : always
openjdk 21-ea 2023-09-19
OpenJDK Runtime Environment (build 21-ea+12-971)
OpenJDK 64-Bit Server VM (build 21-ea+12-971, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Given a generic method that is intended to be invoked, javac will accept the invocation if the code for the parameter is directly nested within the invocation, but not if this argument is extracted into a local variable first and then this variable is applied to the method. Specifically note the two classes (intended as two separate test cases) given. The test case corresponding to class Test1 puts the code for the first argument of test2 directly in the method invocation. The test case corresponding to class Test2 extracts the code for the first argument and first puts it in a local variable. Regardless of this seemingly irrelevant change in the code, the second test case no longer compiles. It is my opinion that the original code should have never been valid to begin with and should have been rejected by javac.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the code within class Test1 - this should be allowed. Now try to compile the code within class Test2 - this is not allowed.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
javac should be consistent in whether the method invocation is valid or not, even when the code for the method argument is extracted into a local variable. The consistent result should be that both code snippets fail since the result of asSubclass is of type Class<? extends Number>, hence type argument U gets the form of ? extends Number, whereas the original type is of T extends Number. The actual type described by these may not be the same, but this is mandated by the contract of method test2.
ACTUAL -
javac is inconsistent with regards to the applicability of the method invocation. If the argument is lifted to a local variable, the method invocation is no longer valid.
---------- BEGIN SOURCE ----------
public class Test1 {
private <T extends Number> void test(T y) throws ClassNotFoundException {
test2(Class.forName("x").asSubclass(Number.class), y);
}
private <U> void test2(Class<U> x, U y) {}
}
public class Test2 {
private <T extends Number> void test(T y) throws ClassNotFoundException {
var x = Class.forName("x").asSubclass(Number.class);
test2(x, y);
}
private <U> void test2(Class<U> x, U y) {}
}
---------- END SOURCE ----------
FREQUENCY : always