Extrair generics com reflection

Pessoal,

Se eu declarar uma collection como abaixo:

Vector<MinhaClasse> vetor = new Vector<MinhaClasse>();

Tem como eu recuperar a referência a MinhaClasse com reflection, ou seja, tem como eu saber que tipo de objeto está vindo nesta collection?

Obrigado

A resposta simples é "não", devido ao conceito de "erasure".
Entretanto, rode e estude o programa abaixo . (Evite criar classes anônimas como as mostradas abaixo; estão aí só para você entender alguns conceitos).

import java.util.*;

class Animal {
}
class Vegetal {
}
class Mamifero extends Animal {
}
class Carnivoro extends Mamifero {
}
class Roedor extends Mamifero {
}
class Cao extends Carnivoro {
}
class Felino extends Carnivoro {
}
class Leao extends Felino {
}
class Gato extends Felino {
}
class Rato extends Roedor {
}

class TesteGenericsReflection {

    public void teste (List&lt? extends Animal&gt lista) {
        System.out.println ("-------");
        System.out.println (lista);
         System.out.println (lista.getClass().getName()); // Veja que imprime "java.util.Vector" ou "java.util.ArrayList", sem o argumento (erasure)
         System.out.println (Arrays.asList (lista.getClass().getGenericInterfaces()));
         System.out.println (Arrays.asList (lista.getClass().getGenericSuperclass()));
         
    }

    public static void main(String[] args) {
        TesteGenericsReflection tgr = new TesteGenericsReflection();
        Vector<Felino> vg = new Vector<Felino>();
        vg.add (new Gato());
        vg.add (new Leao());
        tgr.teste (vg); // imprime "java.util.Vector"
        tgr.teste (new ArrayList<Cao>()); // imprime "java.util.ArrayList"
        // Note que aqui iremos criar 2 classes anônimas!
        tgr.teste (new ArrayList<Rato>() { // imprime "TesteGenericsReflection$1"
        });
        // Cuidado que isto cria outra classe anônima!
        List<Rato> ratos = new ArrayList<Rato>() {
        };
        ratos.add (new Rato());
        ratos.add (new Rato());
        tgr.teste (ratos);
    }
}

Como o thingol disse, não existe uma maneira direta de ter acesso ao parâmetro, mas dependendo da situação existem outras soluções. O que exatamente você quer fazer?

Temos um sistema legado em Kylix que recebe uma estrutura própria em xml contendo dados. O problema é que o Kylix precisa dos metadados, ou seja, tipo dos campos, tamanhos dos campos. Nosso webservice atende as silicitações, gera os xmls e devolve e isso funciona muito bem, desde que a collection que contém nossos VOs ou TOs não esteja vazia, porque daí não conseguimos pegar os metadados deles. O problema é que mesmo que a resposta do servico seja zero “registros” o Kylix necessita dos metadados. Como estamos trabalhado java 5 e possuímos o recurso de generics, pensamos em capturar as informações de metadados diretamente da referência a generics na collection. Um probelmas que temos é que o sistema em kylix é legado, ou seja, não podemos mais fazer alterações nele, então temos que alterar os nossos serviços para atender o kylix. E uma outra coisa, a conversão para xml que o kylix precisa receber é feita automaticamente, por isso precisamos pegar o tipo de objetos que a collection deveria possuir em runtime.

Obrigado pela atenção

[code]package project2;

import java.lang.reflect.*;

public class Class1 {

List<X> xs;
List<String> ys;

public static void main(String[] args) throws Exception {

    Field[] fields = Class1.class.getDeclaredFields();
    for (Field f: fields) {
        ParameterizedType type = (ParameterizedType) f.getGenericType();
        Type[] types = type.getActualTypeArguments();
        System.out.printf("%s, %s \n",type,types[0]);
    }
}

}

class X {
public int a;
}
[/code]

Estou com o mesmo tipo de problema: identificar o tipo de uma lista.

Recuperar o tipo de um array é possível:String[] list = new String[] {"I", "II", "III"}; System.out.println(list.getClass().getComponentType().getName());Output:

java.lang.String

Estou realizando a implementação de um conversor genérico para o JSF baseado no artigo Generic converter for domain model in JSF.

O meu problema ocorre quando tenho um selectManyCheckBox, pois o valor dele é uma lista. Então, ao recuperar o tipo do valor do componente [component.getValueBinding(“value”).getType(context)], o tipo lista é retornado. Porém, preciso saber o tipo dessa lista.

Com a possibilidade de recuperar essa informação usando um array, acho que vou substituir a lista por um array. O que vocês pensam sobre isso?