Sobes.tech
Middle+

Je možné počas behu programu získať prístup k typu generika?

sobes.tech AI

Odpoveď od AI

Nie, to nie je možné. Informácie o type generika sa počas kompilácie vymazávajú (type erasure). Počas behu sú dostupné iba "surové" typy.

Napríklad:

List<String> strings = new ArrayList<>();
// Počas behu programu tieto informácie budú stratené:
// type erasure

Preto nasledujúci kód nebude fungovať tak, ako by sa očakávalo:

if (list instanceof List<String>) { // Chyba kompilácie alebo varovanie
    // Tento kód nebude fungovať ako kontrola na List<String>
}

Informácie o type generika je možné získať pomocou reflexie, ale len v určitých prípadoch, napríklad pri práci s poľami, metódami alebo signatúrami tried, kde bol typ explicitne uvedený v zdrojovom kóde.

Príklad získania typu kolekcie z poľa:

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ískame Type obsahujúci informácie o <>

        if (genericType instanceof ParameterizedType) { // Kontrolujeme, či je typ parametrizovaný
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Získame argumenty typu

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

Získať typ prvku zoznamu, ktorý bol vytvorený dynamicky, už nie je možné:

List<Integer> intList = new ArrayList<>();
// Tu je informácia o Integer stratená v runtime

V kontexte Android je to obzvlášť dôležité pri práci s knižnicami využívajúcimi generiká, napríklad Retrofit na parsovanie odpovedí z API. Často sa používajú konštrukcie typu TypeToken z Guava alebo jeho ekvivalentov na prenos informácií o type počas behu.

Príklad použitia TypeToken (z Guava):

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

Type listStringType = new TypeToken<List<String>>() {}.getType();
// Tento objekt Type obsahuje informácie o List<String> a môže byť použitý v runtime