Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
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
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang