JDK-5105887 : There should be way to create generic arrays without warnings or errors
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2004-09-22
  • Updated: 2004-09-28
  • Resolved: 2004-09-28
Related Reports
Duplicate :  
Relates :  
Description

Name: rmT116609			Date: 09/22/2004


FULL PRODUCT VERSION :
java version "1.5.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Linux router 2.6.8.1 #1 Mon Aug 16 23:49:22 CEST 2004 i686 athlon i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
There is no way to efficently create generic arrays without compiler warnings.

Compiler messages are used to indicate that some source code should be changed (e.g. due to a error). After the change, the compiler warning is not  issued anymore. For the creation of generic arrays, no such change is available.

Additionally, the reasoning in http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf , page 15, is not quite exact:

A creation of an array of a generic type is not dangerous by itself, if it is just just to set or get elements of that generic type. The danger exists only if the compiler is not able to track the intended generic type of a concrete array. Thus, in the example provided by the generics tutorial,

  List<String>[] lsa = new List<String>[10];
  Object o = lsa;

not the first line should result in a compile time error, but the second line should. This is, because the generic array type List<String>[] is implicitly casted to the non-generic non-array type Object. (This is the only non-array type one can cast an array to.) It is due to the cast, that the compiler cannot track what the intended type of the generic array is, not because a generic array can exist in general. There should never be any warnings or error message issued for cases, where invariants (e.g. the generic type of an array element) can be proven to hold.

n
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the source code provided with

(1)
javac com/mn/tools/test/bugs/java/GenericArrayTest.java
(2)
javac -Xlint:unchecked com/mn/tools/test/bugs/java/GenericArrayTest.java
(3)
javac -Xlint:-unchecked com/mn/tools/test/bugs/java/GenericArrayTest.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
(1)
<empty message>
(2)
com/mn/tools/test/bugs/java/GenericArrayTest.java:15: warning: [unchecked] unchecked cast
found   : java.lang.Object[]
required: T[]
                return (T[]) new Object[size];
                             ^
1 warning
(3)
<empty message>

ACTUAL -
(1)
Note: com/mn/tools/test/bugs/java/GenericArrayTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
(2)
com/mn/tools/test/bugs/java/GenericArrayTest.java:15: warning: [unchecked] unchecked cast
found   : java.lang.Object[]
required: T[]
                return (T[]) new Object[size];
                             ^
1 warning
(3)
Note: com/mn/tools/test/bugs/java/GenericArrayTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/** GenericArrayTest.java
*/

package com.mn.tools.test.bugs.java;

/**
	Tests for a compile without warning.
*/
public class GenericArrayTest<T> {

	public T[] createAnArray(int size) {
//		This results in error "generic array creation"
//		return new T[size];
//		This results in warning "warning: [unchecked] unchecked cast"
		return (T[]) new Object[size];
	}
}
// :indentSize=8:tabSize=8:
---------- END SOURCE ----------
(Incident Review ID: 311052) 
======================================================================

Comments
EVALUATION First, due to erasure, there is no way to create an array from a type variable. The required type information is simply not available at runtime. See rfe 5098163. Secondly, whether or not the Generics Tutorial is exact is a matter of opinion. The real problem is that arrays are not statically type safe. This is due to the subtype relation that states that T[] is a subtype of S[] if T is a subtype of S. This means that we must either disallow creation of generic arrays or give warnings in cases like: List<String>[] ss = ...; List<?>[] l1 = ss; // warning? List[] l2 = ss; // warning? Object[] os = ss; // warning? Object o = ss; // warning? Since we cannot implement creation of generic array (since the required type information is not available at runtime), it is forbidden. However you can always make an unchecked cast. In the future it should be possible to suppress unchecked warnings. See rfe 4986256. Generics are supposed to be statically type safe. However, in order to interface with old code and to allow programs which cannot be expressed type safely in the current language, we sometimes allow unsafe expressions but give mandatory warnings (they are required by the language specification). This means that we can give a type safety guarantee: "if your entire application has been compiled without unchecked warnings using javac -source 1.5, it is type safe." An example which demonstrates that why the GenericArrayTest is not type safe: GenericArrayTest<String> g = new GenericArrayTest<String>(); String[] ss = g.createAnArray(); // causes a ClassCastException ###@###.### 2004-09-28
28-09-2004