Passar nome de classe por variável

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” :slight_smile:
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&lt;?&gt; classe = Class.forName (&quot;br.com.teste.Classe2&quot;);
Classe2 obj = (Classe2) classe.newInstance(); // erro de compilação porque não conheço Classe2
obj.processa (&quot;Rafael&quot;, 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&lt;?&gt; classe = Class.forName (&quot;br.com.teste.Classe2&quot;);
Processavel obj = (Processavel) classe.newInstance(); // agora que conheço Processavel posso chamar o método processa.
obj.processa (&quot;Rafael&quot;, 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&lt;Processavel&gt; 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&lt;? extends JDialog&gt; classe = Class.forName (&quot;minha.tela.que.eh.derivada.de.JDialog&quot;).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.