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