Sobes.tech
Middle+

Je možné během běhu programu získat přístup k typu generika?

sobes.tech AI

Odpověď od AI

Ne, to není možné. Informace o generickém typu jsou během kompilace smazány (type erasure). V době běhu jsou dostupné pouze "surové" typy.

Například:

List<String> strings = new ArrayList<>();
// Během běhu bude tato informace ztracena:
// type erasure

Proto následující kód nebude fungovat tak, jak by se dalo očekávat:

if (list instanceof List<String>) { // Chyba kompilace nebo varování
    // Tento kód nebude fungovat jako kontrola na List<String>
}

K informacím o typu generického typu lze přistupovat pomocí reflexe, ale pouze v určitých případech, například při práci s poli, metodami nebo signaturami tříd, kde byl typ explicitně uveden v zdrojovém kódu.

Příklad získání typu kolekce z pole:

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(); // Získáme Type obsahující informace o <>

        if (genericType instanceof ParameterizedType) { // Kontrola, zda je typ parametrizovaný
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Argumenty typu

            for (Type type : actualTypeArguments) {
                System.out.println("Typ prvku: " + type.getTypeName()); // Vytiskne "java.lang.String"
            }
        }
    }
}

Ale není možné získat typ prvku dynamicky vytvořeného seznamu:

List<Integer> intList = new ArrayList<>();
// Zde informace o Integer je ztracena při běhu

V kontextu Android je to obzvlášť důležité při práci s knihovnami využívajícími generiky, například Retrofit pro parsování odpovědí API. Často se používají konstrukce typu TypeToken z Guava nebo jejich ekvivalentů pro předání informace o typu během běhu.

Příklad použití TypeToken (z Guava):

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

Type listStringType = new TypeToken<List<String>>() {}.getType();
// Tento objekt Type obsahuje informace o List<String> a může být použit v době běhu