Galera é o seguinte, alguém alguma maneira de eu passar uma nome de uma classe por uma variável e depois poder instanciar esta classe pela variável?
Ex.
String nomeClasse = “Produto”;
new nomeClasse();
Abraço a todos.
Fabio Souza
Galera é o seguinte, alguém alguma maneira de eu passar uma nome de uma classe por uma variável e depois poder instanciar esta classe pela variável?
Ex.
String nomeClasse = “Produto”;
new nomeClasse();
Abraço a todos.
Fabio Souza
Class aClasse = Class.forName("java.lang.String");
Object objeto = aClasse.newInstance();
Se você precisar de chamar um construtor com parâmetros, é necessário usar a classe java.lang.reflect.Constructor.
public static void main( String[ ] args ) throws ParseException, InstantiationException, IllegalAccessException, ClassNotFoundException {
String objetoString = "";
String nomeClasse = objetoString.getClass( ).getName( );
Object novaInstancia = Class.forName( nomeClasse ).newInstance( );
}
Faça seus casts a vontade.
Ps.: Meu nome é bem parecido com o seu. “Fábio Zoroastro de Souza”
Abraço.
Vc pode usar a classe Class…
Class minhaClasse = minhaClasse.class;
Object obj = minhaClass.newInstance();
ou
Class<MinhaClasse> minhaClasse = minhaClasse.class;
MinhaClasse obj = minhaClass.newInstance();
como eu poderia fazer casting usando a mesma variável para fazer isso.
abraço.
Nesse ponto, não dá para fazer o que você quer (para começar, por que é que você precisaria do casting, hein?)
Em 99% dos casos, na prática você tem o seguinte problema, e é assim que se resolve:
Você tem várias classes que tem um determinado método (digamos que o nome dele seja "processa" e eu preciso passar 3 parâmetros para ele). O método seria:
public double processa (String nome, double quantidade, int[] chaves);
De algum outro lugar (digamos um arquivo de configuração), você lê o nome das classes que implementam esse código processa. Digamos que você tenha:
package br.com.teste;
class Classe1 {
public double processa (String nome, double quantidade, int[] chaves) {
return quantidade * 10;
}
}
class Classe2 {
public double processa (String nome, double quantidade, int[] chaves) {
return quantidade * 7 + chaves[1];
}
}
Agora você quer fazer o seguinte: criar um objeto da classe br.com.teste.Classe2 e chamar o método processa com os parâmetros "Rafael", 200 e new int[]{20, 30}. Você provavelmente iria querer fazer:
Class<?> classe = Class.forName ("br.com.teste.Classe2");
Classe2 obj = (Classe2) classe.newInstance(); // erro de compilação porque não conheço Classe2
obj.processa ("Rafael", 200, new int[]{20, 30});
Mas obviamente você não pode fazer isso, porque não sabe o nome para poder fazer o tal do casting.
Você até, usando reflection, chamar o método processa com esses parâmetros, mas é chato e lento usar reflection nesse caso (porque você tem de ficar preparando os parâmetros e outras coisas chatas e burocráticas). Em vez disso, você pode fazer o seguinte:
package br.com.teste;
interface Processavel {
double processa (String nome, double quantidade, int[] chaves);
}
...
class Classe1 implements Processavel {
public double processa (String nome, double quantidade, int[] chaves) {
return quantidade * 10;
}
}
class Classe2 implements Processavel {
public double processa (String nome, double quantidade, int[] chaves) {
return quantidade * 7 + chaves[1];
}
}
e na hora de chamar o tal método processa, você faz:
Class<?> classe = Class.forName ("br.com.teste.Classe2");
Processavel obj = (Processavel) classe.newInstance(); // agora que conheço Processavel posso chamar o método processa.
obj.processa ("Rafael", 200, new int[]{20, 30});
Isso funciona bem, é rápido, não precisa de chongas nenhumas de reflection, lhe ajuda a definir corretamente os parâmetros do método, e força você a ser organizado.
Tem gente que diz que pode usar:
Class<Processavel> classe = Class.forName ("br.com.teste.Classe2").asSubclass (Processavel.class);
Processavel obj = classe.newInstance(); // agora que conheço Processavel posso chamar o método processa.
obj.processa ("Rafael", 200, new int[]{20, 30});
Isto é um pouco mais complicado, mas quem não gosta de casts (prefere que o compilador faça o serviço sujo) pode usar a opção acima.
O motivo para eu querer fazer isso é o seguinte, eu estou criando uma menu com Jtree e queria criar um método genérico para abrir as telas do sistema, quando o usuário desse um duplo clique na opção do jtree eu chamaria este método e abriria a tela.
As telas do seu sistema são classes que são derivadas a partir de JFrame, JPanel, JInternalFrame ou JDialog? Basta fazer algo como (digamos que as telas derivam de JDialog: )
Class<? extends JDialog> classe = Class.forName ("minha.tela.que.eh.derivada.de.JDialog").asSubclass (JDialog.class);
JDialog tela = (JDialog) classe.newInstance();
tela.setVisible (true);
essa é boa, hoje mesmo vou testar, só vou terminar algumas coisas que estou fazendo e vou testar o resto.