Zdravím,

když se lidi ze Sunu rozhodovali, jak implementovat generics, tak vybrali
zpětně kompatibilní a nejjednodušší způsob: Type erasure [1].
Generické i negenerické třídy vypadají po zkompilování stejně. Kontrolu
provádí jen kompilátor. V bytecode o aktuálních type parametrech nic není,
takže se na to v runtime nemůžete ptát.

Ve vašem případě není T nijak omezené, takže upper bound je
java.lang.Object. V println by kompilátor zkonvertoval
T.class.getName() na ekvivalent Object.class.getName(), což by pak nemělo
nijakou souvislost s T a bylo by to matoucí.

Mě k pochopení pomohlo si pročíst specifikaci k jazyku Scala [2], kde se
typům věnuje mnohem větší pozornost.
Pěkný je i příklad, jak implementovat generika bez další speciální syntaxe
jen s pomocí abstraktních typů kapitola 5.3 Scala Overview [3].

[1] http://download.oracle.com/javase/tutorial/java/generics/erasure.html
[2] http://www.scala-lang.org/docu/files/ScalaReference.pdf
[3] http://www.scala-lang.org/docu/files/ScalaOverview.pdf

Omluvte anglicismy,
Petr Janata

From: "Libor Jelinek" <[email protected]>
> To: Java <[email protected]>
> Cc:
> Subject: Generické typy a .class - "Cannot select from a type variable"
> Date: Sun, 12 Jun 2011 12:21:16 +0200
>
> Hezké nedělní poledne!
> Možná jsem málo studoval genericitu, ale proč není možné použít T.class (a
> T.class.getName() apod.) v tomto případě?
>
> public class NewClass<T> {
>
>     public NewClass() {
>          System.out.println("Zavolali jste mě s typem " +
> T.class.getName());
>     }
>
>     public static void main(String[] args) {
>         new NewClass<String>();
>         new NewClass<Integer>();
>     }
> }
>
> NetBeans varuje hláškou: "Cannot select from a type variable".
>
> Pokus o překlad dopadne chybou:
>
> Exception in thread "main" java.lang.RuntimeException: Uncompilable source
> code - Erroneous tree type: <any>
>     at beantablemodel.NewClass.<init>(NewClass.java:14)
>     at beantablemodel.NewClass.main(NewClass.java:18)
> Java Result: 1
>
> Vždyť to je známo jaký objekt jsem dodal (new NewClass<String>()) a na
> každý objekt je možné použít .class...
>
> Díky za odpovědi!
> Libor
>

Odpovedet emailem