Estoy usando java generics y varargs.ClassCastException durante el uso de varargs y genéricos
Si uso el siguiente código, obtendré un ClassCastException
, aunque no estoy utilizando moldes en absoluto.
Más extraño aún, si ejecuto esto en Android (dalvik), no se incluye ningún rastro de pila con la excepción, y si cambio la interfaz a clase abstracta, la variable de excepción e
está vacía.
El código:
public class GenericsTest {
public class Task<T> {
public void doStuff(T param, Callback<T> callback) {
// This gets called, param is String "importantStuff"
// Working workaround:
//T[] arr = (T[]) Array.newInstance(param.getClass(), 1);
//arr[0] = param;
//callback.stuffDone(arr);
// WARNING: Type safety: A generic array of T is created for a varargs parameter
callback.stuffDone(param);
}
}
public interface Callback<T> {
// WARNING: Type safety: Potential heap pollution via varargs parameter params
public void stuffDone(T... params);
}
public void run() {
Task<String> task = new Task<String>();
try {
task.doStuff("importantStuff", new Callback<String>() {
public void stuffDone(String... params) {
// This never gets called
System.out.println(params);
}});
} catch (ClassCastException e) {
// e contains "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;"
System.out.println(e.toString());
}
}
public static void main(String[] args) {
new GenericsTest().run();
}
}
Si ejecuta este, obtendrá un ClassCastException
que Object
no se puede convertir a String
con seguimiento de la pila que apunta a la línea número válido. ¿Es esto un error en Java? Lo probé en Java 7 y Android API 8. Hice una solución para esto (comentada en el doStuff
-method), pero parece tonto tener que hacerlo de esta manera. Si elimino varargs (T...
), todo funciona bien, pero mi implementación real lo necesita.
StackTrace de excepción es:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at GenericsTest$1.stuffDone(GenericsTest.java:1)
at GenericsTest$Task.doStuff(GenericsTest.java:14)
at GenericsTest.run(GenericsTest.java:26)
at GenericsTest.main(GenericsTest.java:39)
¿existe una posibilidad de que podría proporcionar una copia de la StackTrace. Mi sospecha es que es del elenco implícito que ocurre debido al borrado de tipo. – Matt
Se agregó rastro de pila a la pregunta. – murgo