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