Sobes.tech
Middle+

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