|
Quick Lists
|
|
Bug ID:
|
6507024
|
|
Votes
|
1
|
|
Synopsis
|
unchecked conversion between arrays fails after capture conversion
|
|
Category
|
java:compiler
|
|
Reported Against
|
|
|
Release Fixed
|
7(b29)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
2-High
|
|
Related Bugs
|
6508599
|
|
Submit Date
|
21-DEC-2006
|
|
Description
|
FULL PRODUCT VERSION :
xxxxx@xxxxx :~/$ java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
xxxxx@xxxxx :~/$ javac -version
javac 1.6.0
ADDITIONAL OS VERSION INFORMATION :
Linux, Debian 3.0
Linux whirl 2.6.12.2 #1 SMP Sun Jul 10 16:49:53 PDT 2005 i686 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
When compiling a class containing the following code:
public <T> void process (Action action, Result<T> results[])
{
// unrelated problem stuff happens
Result<T>[] singleResult = results.getClass().cast(Array.newInstance(results.getClass().getComponentType(), 1));
// more problem-unrelated stuff happens
}
one receives a compiler error similar to:
[depend] Deleted 38 out of date files in 0 seconds
[echo] Building...
[javac] Compiling 142 source files to .../classes
[javac] .../SomeClass.java:88: incompatible types
[javac] found : capture#69 of ? extends some.pacakge.Result[]
[javac] required: some.package.Result<T>[]
[javac] results.getClass().cast(Array.newInstance(
[javac] ^
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 1 error
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. create a function that has a generic type passed in.
2. instantiate an array using the component type of a passed-in array argument of the generic type
3. try and cast the newly-instantiated array to the generic type
4. assign the customer resulting from step 3 to a reference of the generic type.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the compiler to successfully compile the code as the JDK 1.5 compiler did.
ACTUAL -
I received a compiler error similar to:
[depend] Deleted 38 out of date files in 0 seconds
[echo] Building...
[javac] Compiling 142 source files to .../classes
[javac] .../SomeClass.java:88: incompatible types
[javac] found : capture#69 of ? extends some.pacakge.Result[]
[javac] required: some.package.Result<T>[]
[javac] results.getClass().cast(Array.newInstance(
[javac] ^
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 1 error
ERROR MESSAGES/STACK TRACES THAT OCCUR :
I received a compiler error similar to:
[depend] Deleted 38 out of date files in 0 seconds
[echo] Building...
[javac] Compiling 142 source files to .../classes
[javac] .../SomeClass.java:88: incompatible types
[javac] found : capture#69 of ? extends some.pacakge.Result[]
[javac] required: some.package.Result<T>[]
[javac] results.getClass().cast(Array.newInstance(
[javac] ^
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
See description.
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
For now, I am going to have a 2nd generic type, passed-in as a parameter to the function which can be used as a model of what return type to expect.
Posted Date : 2006-12-21 07:34:51.0
|
|
Work Around
|
N/A
|
|
Evaluation
|
Unfortunately, no reproducible test case was submitted so I had to write my own:
import java.lang.reflect.Array;
class Test {
interface Result<T> {}
<T> void m(Result<T>[] results) {
Result<T>[] r = results.getClass().cast(null);
}
}
Since the argument to cast are immaterial to this problem, I have
simply used null.
The type of results.getClass() is Class<? extends Result[]>.
Consequently the type of results.getClass().cast(null) is
the capture of ? extends Result[].
So the question is: is there there an unchecked conversion from
the capture of ? extends Result[] to Result<T>[]?
According to the compiler there is one from Result[] to Result<T>[]
which should imply that there is one from the capture of
? extends Result[].
I cannot find anything in the JLS to support any of this so it appears
that there is a JLS bug as well. This is understandable as it is not
recommended that arrays and generic types are mixed as in the example.
I assume that this is indeed a compiler error and filed specification
bug number 6508599.
Posted Date : 2006-12-29 20:13:26.0
The corresponding JLS bug has been addressed; as Alex says, there should be an unchecked conversion from C[] to C<T>[] and, as a consequence, between a captured type variable whose upper bound is C[] and C<T>[]. Javac seems capable of handling unchecked conversion between arrays already. The problem only affects captured types; this is due to the fact that the code inside Types.isUncheckedSubtype applies array subtyping ONLY if both types S and T in a subtyping test S <: T are arrays. In the submitted example S is not an array (it's a captured type variable). This causes the bug.
In order to solve this problem, we should add some propagation to the algorithm in Types.isSubtypeUnchecked:
if S is a type variable, then call Types.isSubtypeUnchecked recursively where T' = T and S' = upper(S).
Posted Date : 2008-05-29 11:04:17.0
|
|
Comments
|
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |