FULL PRODUCT VERSION :
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux router 2.6.11.2 #7 Sat Mar 12 01:53:23 CET 2005 i686 athlon i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The generics tutorial talks in section 8 about "Class Literals as Run-time Type Tokens", a way to safely deal with generic types, especially when it comes to creating instances of that type.
For example, if you have "Class<T> klass", then you can create an instance "T instane = klass.newInstance()". However, this does not apply to arrays.
The reason might be that java.lang.reflect.Arrays.newInstance() was forgotten in the course of the "genericification" of the core classes to be "genericified" correctly.
The declaration of this method reads as follows:
public static Object newInstance(Class<?> componentType, int[] dimensions)
throws IllegalArgumentException, NegativeArraySizeException {
...
}
but it should read as follows:
public static <T> T[] newInstance(Class<T> componentType, int[] dimensions)
throws IllegalArgumentException, NegativeArraySizeException {
...
}
It should return a generic type, like the declaration of java.lang.Class.newInstance() does:
public T newInstance()
throws InstantiationException, IllegalAccessException
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the test case below, e.g. using "javac -source 1.5 -g com/mn/tools/test/bugs/java/GenericArrayTest3.java"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compile should succeed, maybe with warnings due to unchecked casts.
"Note: com/mn/tools/test/bugs/java/GenericArrayTest3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details."
ACTUAL -
The compile fails
"com/mn/tools/test/bugs/java/GenericArrayTest3.java:22: incompatible types
found : java.lang.Object
required: T[]
return java.lang.reflect.Array.newInstance(getClassFor(anInstance),size);
^
Note: com/mn/tools/test/bugs/java/GenericArrayTest3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/** GenericArrayTest3.java
*/
package com.mn.tools.test.bugs.java;
/**
Tests for a compile without warning.
@author <A HREF="mailto:###@###.###">Xuân Baldauf</A>
*/
public class GenericArrayTest3<T> {
T giveMeANewInstance(T anOldInstance) {
return anOldInstance.getClass().newInstance();
}
T[] giveMeAnArray(T anInstance,int size) {
return java.lang.reflect.Array.newInstance(anInstance.getClass(),size);
}
}
// :indentSize=8:tabSize=8:
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Cast explicitly the return of java.lang.reflect.Array.newInstance() to the desired type.
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux router 2.6.11.2 #7 Sat Mar 12 01:53:23 CET 2005 i686 athlon i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The generics tutorial talks in section 8 about "Class Literals as Run-time Type Tokens", a way to safely deal with generic types, especially when it comes to creating instances of that type.
For example, if you have "Class<T> klass", then you can create an instance "T instane = klass.newInstance()". However, this does not apply to arrays.
The reason might be that java.lang.reflect.Arrays.newInstance() was forgotten in the course of the "genericification" of the core classes to be "genericified" correctly.
The declaration of this method reads as follows:
public static Object newInstance(Class<?> componentType, int[] dimensions)
throws IllegalArgumentException, NegativeArraySizeException {
...
}
but it should read as follows:
public static <T> T[] newInstance(Class<T> componentType, int[] dimensions)
throws IllegalArgumentException, NegativeArraySizeException {
...
}
It should return a generic type, like the declaration of java.lang.Class.newInstance() does:
public T newInstance()
throws InstantiationException, IllegalAccessException
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the test case below, e.g. using "javac -source 1.5 -g com/mn/tools/test/bugs/java/GenericArrayTest3.java"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compile should succeed, maybe with warnings due to unchecked casts.
"Note: com/mn/tools/test/bugs/java/GenericArrayTest3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details."
ACTUAL -
The compile fails
"com/mn/tools/test/bugs/java/GenericArrayTest3.java:22: incompatible types
found : java.lang.Object
required: T[]
return java.lang.reflect.Array.newInstance(getClassFor(anInstance),size);
^
Note: com/mn/tools/test/bugs/java/GenericArrayTest3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/** GenericArrayTest3.java
*/
package com.mn.tools.test.bugs.java;
/**
Tests for a compile without warning.
@author <A HREF="mailto:###@###.###">Xuân Baldauf</A>
*/
public class GenericArrayTest3<T> {
T giveMeANewInstance(T anOldInstance) {
return anOldInstance.getClass().newInstance();
}
T[] giveMeAnArray(T anInstance,int size) {
return java.lang.reflect.Array.newInstance(anInstance.getClass(),size);
}
}
// :indentSize=8:tabSize=8:
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Cast explicitly the return of java.lang.reflect.Array.newInstance() to the desired type.
- duplicates
-
JDK-5101892 (reflect) retrofit Array.newInstance by using generics
- Closed
- relates to
-
JDK-6223347 (reflect) Add a generic replacement for Array.newInstance() to help write type safe code
- Closed