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<? extends Animal> 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?