Sobes.tech
Middle+

Ar galima prieiti prie generinio tipo programos vykdymo metu?

sobes.tech AI

Atsakymas iš AI

Ne, negalima. Informacija apie generiko tipą trinama vykdant (type erasure). Vykdant prieinami tik "gryni" tipai.

Pavyzdžiui:

List<String> strings = new ArrayList<>();
// Vykdant ši informacija bus prarasta:
// type erasure

Todėl šis kodas neveiks taip, kaip tikėtasi:

if (list instanceof List<String>) { // Klaida kompiliuojant arba įspėjimas
    // Šis kodas neveiks kaip patikrinimas ar List<String>
}

Informaciją apie generiko tipą galima gauti naudojant refleksiją, bet tik tam tikrais atvejais, pavyzdžiui, dirbant su laukais, metodais ar klasės signatarais, kur tipas aiškiai nurodytas šaltinio kode.

Pavyzdys, kaip gauti kolekcijos tipą iš lauko:

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(); // Gauname Type, kuris turi informaciją apie <>

        if (genericType instanceof ParameterizedType) { // Patikriname ar tipas yra parametrizuotas
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Gauname tipo argumentus

            for (Type type : actualTypeArguments) {
                System.out.println("Elemento tipas: " + type.getTypeName()); // Išves "java.lang.String"
            }
        }
    }
}

Tačiau dinamiškai sukurtos sąrašo elemento tipo gauti nebeįmanoma:

List<Integer> intList = new ArrayList<>();
// Čia informacija apie Integer prarandama vykdymo metu

Android kontekste tai ypač svarbu, kai dirbate su bibliotekomis, naudojančiomis generikus, pavyzdžiui, Retrofit API atsakymų analizavimui. Dažnai naudojamos TypeToken konstrukcijos iš Guava ar jų analogai, kad perduotų informaciją apie tipą vykdymo metu.

Pavyzdys, kaip naudoti TypeToken (iš Guava):

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

Type listStringType = new TypeToken<List<String>>() {}.getType();
// Šis Type objektas turi informaciją apie List<String> ir gali būti naudojamas vykdymo metu