java statikus eljárásban generic típusa

Fórumok

Sziasztok,
az adott kódban szeretném az ismeretlen típusát lekérdezni, kiírni a képernyőre.


public static <S> S kornyezet(){
  S obj = null;
  /*...*/
  return obj;
}

Mit javasoltok?

SZERKESZTVE:


static{
Float f = miez();
Integer i = miez();
Color c = miez();
}

static <S> S miez(){
  System.out.println(S.class);
  return null;
}

hiba: Illegal class literal for the type parameter S

Hozzászólások

bocs, tényleg nehéz megfogalmazni. A kódban valami S szimbólum jelzi, hogy mivel kell visszatérnie, illetve hogy mit vár a környezete - ha jól értem. ennek a típusára vagyok kíváncsi.
azt szeretném, ha mondjuk a következő kód


Color c = kornyezet();
Integer i = kornyezet();
Map m = kornyezet();

kimenete rendre


Color
Integer
Map

lenne.
megoldható?

Figy, lehet hülye vagyok, de. Mi lenne, ha nem paraméter nélküli lenne a metódusod, hanem kapna egy Class típusú bemeneti paramétert. És akkor úgy hívnák meg, hogy környezet(S.getClass()). És innentől tudod. A metódustörzs nem tud az S-ről, mivel az vísszatérési típus. Viszont nyilván, ha nem megfelelő dologgal fogsz visszatérni, akkor úgyis hibát dob majd.

--
"SzAM-7 -es, tudjátok amivel a Mirage-okat szokták lelőni" - Robi.

az obj referencia - amit visszaadsz - típusa az S parametrizált típus.

public static <S> S kornyezet() {
S obj = null;

for (Method m : Valami.class.getDeclaredMethods()) {
if ("kornyezet".equals(m.getName())) {
System.out.println(m.getGenericReturnType());
}
}

return obj;

}

At fogod látni hogy "S"... mert az a típusa.

Például

public static <S> S doSomething() {
S obj = null;
obj = (S)new ArrayList();
System.out.println(obj.getClass().getName());
return obj;
}

És kiírja hogy java.util.ArrayList... hol tart már a tudomány..

Ez valami SCJP mitírkileforduledobehibát kérdés?

Khm, type erasure?

----------------------
while (!sleep) sheep++;

google.

a genericeket ugy implementaltak, hogy forditaskor van tipusellenorzes, azonban utana minden tipus torlodik [mindezt azert, hogy visszafele kompatibilis maradjon a generalt bytecode].

itt az altalad ahitott kod, csak nem az altalad ahitott kimenettel :-)


final class X<T> {
    private final List<T> x;
    
    public X() {
        x = null;
    }

    public void printType() {
        for(Field f : this.getClass().getDeclaredFields())
            System.out.println(((ParameterizedType)f.getGenericType()).getActualTypeArguments());
    }
}

public class Main {
    public static <S> S kornyezet() {
        X<S> p = new X<S>();
        p.printType();
        return null;
    }
}

??? Hát én kipróbáltam. Kiírja egy tömb azonosítóját. A tömbben meg van egy elem (egy Type), az meg egyszerűen Integer helyett(azt példányodítottam) T.
Futásidőben sehogy nem lehet lekérdezni egy generic valós típusát (kiveve ha mar van benne elem, de az gany.).
Vagy akkor nem értem.
De pl. a kornyezet fv. visszateresi erteke is rejtely.
Lecci ha mar kinyilatkoztatsz, akkor vesd kozenk hatalmas tudasod morzsait is...
:-)

nem tudasmorzsakrol van itt szo, csak napi sokoraban javazok, igy sokmindenbe belefutottam mar. de most Nalad a pont.

a tortenet (itt lehet ugrani ha vkit nemerdekel a magyarazkodas:P) az, hogy szuksegem lett volna nekemis erre (pontosabban en a tipusparametert szerettem volna peldanyositani..), es nem is talaltam ra megoldast, termeszetesen a futas kozbeni tipusparametereket a type erasure elnyeli (igy fent is).

viszont _nem_ mindent nyel el, amit lent irtam, hogy ki lehet nyerni a generikus tipust tovabbra is tartom, hiszen a tipusdeklaracio resze lesz.


public class Main {
    private List<Integer> i;

    public static void main(String[] args) {
        for(Field f : Main.class.getDeclaredFields()) {
            System.out.println(((ParameterizedType)f.getGenericType()).getActualTypeArguments()[0]);
        }
    }
}

Futasidoben nem lehet lekerdezni a tipusparameter tipusat (nincs "reification").
Nehany kovetkezmeny:

  • egy T tipusparameterre nem ertelmezheto, hogy T.class
  • nem hasznalhato az instanceof annak eldontesere, hogy egy objektum T tipusu-e
  • nem hozhato letre egy T elemekbol allo tomb
  • nem irhatok class literalok generikus tipusokra (List<String>.class)
  • nem hasznalhato az instanceof annak eldontesre, hogy az objektum List<String> tipusu-e
  • nem hozhato letre List<String> elemekbol allo tomb
  • stb.

A 7-es Javaban volt szo a Reification megvalositasarol, de vegul kimaradt, mivel tul nagy teruletet erintett volna.

Sziasztok,
köszönöm a gyors válaszaitokat. Sok érdekesség elhangzott, nagyon tanulságos volt. Azt hiszem, a kérdés megoldva.
Jó éjt,
zepp.