Sobes.tech
Middle+

¿Es posible acceder al tipo de genérico durante la ejecución del programa?

sobes.tech AI

Respuesta de la IA

No, no se puede. La información sobre el tipo genérico se borra durante la compilación (tipo erasure). Solo están disponibles los "tipos en bruto" en tiempo de ejecución.

Por ejemplo:

List<String> strings = new ArrayList<>();
// Durante la ejecución, esta información se perderá:
// type erasure

Por lo tanto, el siguiente código no funcionará como se espera:

if (list instanceof List<String>) { // Error de compilación o advertencia
    // Este código no funcionará como una comprobación de List<String>
}

Se puede acceder a la información del tipo genérico mediante reflexión, pero solo en ciertos casos, por ejemplo, al trabajar con campos, métodos o firmas de clases donde el tipo fue especificado explícitamente en el código fuente.

Ejemplo de obtención del tipo de colección desde un campo:

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public class MyClass {
    List<String> stringList;

    public static void main(String[] args) throws Exception {
        Field field = MyClass.class.getDeclaredField("stringList");
        Type genericType = field.getGenericType(); // Obtenemos un Type que contiene la información de <>

        if (genericType instanceof ParameterizedType) { // Verificamos si el tipo está parametrizado
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Obtenemos los argumentos del tipo

            for (Type type : actualTypeArguments) {
                System.out.println("Tipo del elemento: " + type.getTypeName()); // Mostrará "java.lang.String"
            }
        }
    }
}

Pero no será posible obtener el tipo del elemento de una lista creada dinámicamente:

List<Integer> intList = new ArrayList<>();
// Aquí, la información sobre Integer se pierde en tiempo de ejecución

En el contexto de Android, esto es especialmente importante al trabajar con bibliotecas que usan genéricos, como Retrofit para analizar respuestas de API. A menudo, se utilizan construcciones como TypeToken de Guava o sus análogos para pasar información del tipo en tiempo de ejecución.

Ejemplo de uso de TypeToken (de Guava):

import com.google.common.reflect.TypeToken;
import java.util.List;

Type listStringType = new TypeToken<List<String>>() {}.getType();
// Este objeto Type contiene información sobre List<String> y puede usarse en tiempo de ejecución