java - tipos - ¿Cómo obtengo el atributo `.class` de un parámetro de tipo genérico?
programacion orientada a objetos java pdf (3)
Lo hice así:
Esta es mi definición de clase:
public class ManagerGeneric <T> {
Esto está en mi método:
// Get the type of generic parameter
Type typeOfT = new TypeToken<T>(){}.getType();
// Deserialize
T data = gson.fromJson(json, typeOfT);
La respuesta aceptada a esta pregunta describe cómo crear una instancia de T
en la clase Generic<T>
. Esto implica pasar un parámetro Class<T>
al constructor Generic
y newInstance
método newInstance
partir de eso.
Se crea una nueva instancia de Generic<Bar>
y se pasa el parámetro Bar.class
.
¿Qué hace si el parámetro de tipo genérico para la nueva clase Generic
no es una clase conocida como Bar
sino que es un parámetro de tipo genérico? Supongamos que tengo otra clase de Skeet<J>
y quiero crear una nueva instancia de Generic<J>
desde el interior de esa clase. Entonces, si trato de pasar a J.class
, obtengo el siguiente error de compilación:
cannot select from a type variable.
¿Hay alguna forma de evitar esto?
El bit específico de código que desencadena el error para mí es:
public class InputField<W extends Component & WidgetInterface>
extends InputFieldArray<W>
{
public InputField(String labelText)
{
super(new String[] {labelText}, W.class);
}
/* ... */
}
public class InputFieldArray<W extends Component & WidgetInterface>
extends JPanel
{
/* ... */
public InputFieldArray(String[] labelText, Class<W> clazz)
throws InstantiationException, IllegalAccessException
{
/* ... */
for (int i = 0 ; i < labelText.length ; i++) {
newLabel = new JLabel(labelText[i]);
newWidget = clazz.newInstance();
/* ... */
}
/* ... */
}
/* ... */
}
El error ocurre, porque no puedo escribir W.class
. ¿Hay alguna otra forma de transmitir la misma información?
No se permite el uso de .class
en un parámetro de tipo: debido al borrado de tipo , W
se habrá borrado a Component
en el tiempo de ejecución. InputField
también tendrá que tomar una Class<W>
de la persona que llama, como InputFieldArray
:
public InputField(String labelText, Class<W> clazz)
{
super(new String[] {labelText}, clazz);
}
W puede no estar disponible debido a borrado de tipo. Debería requerir que se pase una Class<W>
al método. Obtienes un objeto de clase y su genérico asegura que solo W
y ninguna subclase se pasen, debido a la covarianza.
public InputField(String labelText, Class<W> cls)
{
super(new String[] {labelText}, cls);
}
tomará W.class
pero no WSubtype.class
.