como faço para instanciar uma classe que eu desconheço o tipo dela? sem usar Object pois isto não me dara acesso a todos os metodos desta classe…
por exemplo:
quero fazer dinamicamente isto:
Method metodoVO = vo.getClass().getMethods[x];
Cachorro c = metodoVO.invoke(vo).newInstance();
sabendo-se que isto metodoVO.invoke(vo).newInstance(); seria uma instancia da classe Cachorro como faço um cast dinamicamente para o tipo Cachorro usando String se possivel?
Uma variável não pode ter um tipo dinâmico, portanto você só poderia usar uma variável do tipo Object. Certo?
Para poder usar um método da tal classe, você tem de usar invoke mesmo, com o valor dessa variável do tipo Object. É por isso que invoke aceita um parâmetro do tipo Object, não um parâmetro de algum tipo mais restrituo.
Esse tipo de coisa normalmente está berrando para usar interfaces. Se todas as classes que forem instanciadas por nome implementarem uma determinada interface, basta invocar os métodos dela usando uma variável de interface, não uma variável de classe. Por exemplo:
interface Animal { void emitirRuido (); }
class Cachorro implements Animal { public void emitirRuido () { System.out.println ("au!"); }}
class Gato implements Animal { public void emitirRuido () { System.out.println ("miau!"); }}
...
Animal toto = (Animal) Class.forName ("Cachorro").newInstance();
Animal nino = (Animal) Class.forName ("Gato").newInstance();
toto.emitirRuido();
nino.emitirRuido();
[quote=thingol]Uma variável não pode ter um tipo dinâmico, portanto você só poderia usar uma variável do tipo Object. Certo?
Para poder usar um método da tal classe, você tem de usar invoke mesmo, com o valor dessa variável do tipo Object. É por isso que invoke aceita um parâmetro do tipo Object, não um parâmetro de algum tipo mais restrituo.
[/quote]
Com Generics, é possível que uma variável tenha tipo dinâmico. Afinal, Generics é justamente isso.
Poderia fazer algo assim…
public <E> void metodo(Class<E> arg ", outros_parametros") {
...
E variavel = (E)metodoVO.invoke(vo).newInstance();
}
//Para chamar o metodo vc teria que informar qual vai ser a classe. Ex.:
public static void main(String... args){
//...instancia x
x.metodo(Cachorro.class ", outros argumentos");
O tipo genérico E poderia ter sido declarado na classe e aí não precisaria passar o tipo como parametro do metodo, mas precisaria acessar a classe usando o generico desejado (da maneira que acontece com as coleções).
Ainda assim, da maneira acima não teria como invocar os métodos de Cachorro . Se vc quisesse, deveria restringir o tipo generico para um subtipo de Cachorro trocando <E> por <E extends Cachorro>… aí vc poderia chamar os metodos de Cachorro (mas nao poderia usar outros tipos que nao passem no teste E É-UM Cachorro).
hehehe… mas tenho alguns problemas… bem o que eu quero fazer e o seguinte: eu tenho o seguinte cenario:
tenho varias classes VOs com varios tipos de atributos diferentes e varias classes ViewBeans que tem os mesmos nomes dos atributos do VO porem todos eles são Strings… eu sempre tenho que setar todos os atributos dos VOs nos ViewBeans convertendoos em String e formatandoos qdo nesseçario o que eu quero fazer e um metodo generico que faça isto para mim para qualquer classe VO e ViewBean… com tipos wrapers eu consegui… porem a coisa complica qdo um VO tem outro VO dentro… pois terei que fazer uma passada recursiva do VO mas com todos os metodos que ele tem para a conversão não podendo passar Object pois perderei os metodos e nem uma interface ou herança ja que preciso dos metodos da PROPRIA classe e não tenho como adivinhar qual classe sera invocada porem os metodos de cada classe serao diferentes…]
ai que complica meu problema… alguem tem uma solução?
Não, você precisa só de reflection e de um bocado de paciência. Só isso. Não precisa de mais nada. Lembre-se que com reflection você pode chamar qualquer método de qualquer objeto (contanto que ele seja público e você saiba que parâmetros passar) pelo nome.