Kas on võimalik juurdepääs generik-tüübile programmi täitmise ajal?
sobes.tech AI
Vastus AI-lt
Ei, see ei ole võimalik. Generics-tüübi teave kustutatakse kompileerimisel (type erasure). Väljastpoolt on saadaval ainult "toores" tüübid.
Näiteks:
List<String> strings = new ArrayList<>();
// Väljastpoolt käivitamisel kaob see teave:
// type erasure
Seetõttu ei tööta järgmine kood ootuspäraselt:
if (list instanceof List<String>) { // Kompileerimisviga või hoiatus
// See kood ei tööta List<String> kontrollina
}
Informatsiooni generik-tüübi kohta saab refleksiooni abil, kuid ainult teatud juhtudel, näiteks klassi väljade, meetodite või signatuuride puhul, kus tüüp on selgelt määratletud lähtekoodis.
Näide, kuidas saada kollektsiooni tüüp väljast:
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(); // Saame Type, mis sisaldab infot <>
if (genericType instanceof ParameterizedType) { // Kontrollime, kas tüüp on parametriseeritud
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Saame tüübi argumendid
for (Type type : actualTypeArguments) {
System.out.println("Elemendi tüüp: " + type.getTypeName()); // Väljund "java.lang.String"
}
}
}
}
Kuid dünaamiliselt loodud listi elemendi tüüpi ei ole enam võimalik saada:
List<Integer> intList = new ArrayList<>();
// Siin teave Integer kohta kaob runtime ajal
Android kontekstis on see eriti oluline, töötades genrikke kasutavate raamatukogudega, näiteks Retrofit API vastuste parseldamiseks. Seal kasutatakse sageli TypeToken konstruktsioone Guava-st või nende analooge, et edastada teavet tüübi kohta runtime ajal.
Näide TypeToken kasutamisest (Guava-st):
import com.google.common.reflect.TypeToken;
import java.util.List;
Type listStringType = new TypeToken<List<String>>() {}.getType();
// See Type objekt sisaldab infot List<String>-i kohta ja seda saab kasutada runtime ajal