68 votes

Créer une nouvelle classe à partir d'une variable en Java

Est-il possible de créer une nouvelle classe à partir d'une variable String en Java?

 String className = "Class1";
//pseudocode follows
Object xyz = new className(param1, param2);
 

Aussi, si possible, l'objet résultant doit-il être de type Object?

Il existe peut-être un meilleur moyen, mais je veux pouvoir extraire les valeurs d'un fichier XML, puis créer les classes nommées en fonction de ces chaînes. Chacune des classes implémente la même interface et est dérivée de la même classe parente. Je pourrais alors appeler une méthode particulière dans cette classe.

123voto

Dawie Strauss Points 1576

C'est ce que vous voulez faire:

String className = "Class1";
Object xyz = Class.forName(className).newInstance();

Notez que la méthode newInstance ne permet pas une paramétrées constructeur à être utilisé. (Voir La Classe.newInstance documentation)

Si vous avez besoin d'un paramétrées constructeur, c'est ce que vous devez faire:

import java.lang.reflect.*;

Param1Type param1;
Param2Type param2;
String className = "Class1";
Class cl = Class.forName(className);
Constructor con = cl.getConstructor(Param1Type.class, Param2Type.class);
Object xyz = con.newInstance(param1, param2);

Voir Le Constructeur.newInstance documentation

14voto

Brabster Points 18764

Oui, vous pouvez charger une classe sur votre classpath donné le nom de la Chaîne à l'aide de la réflexion, à l'aide de la Classe.forName(nom), en saisissant le constructeur et de l'appeler. Je vais vous faire un exemple.

Considérons j'ai une classe:

com.crossedstreams.thingy.Foo

Qui a un constructeur avec signature:

Foo(String a, String b);

Je voudrais créer une instance de la classe sur la base de ces deux faits comme suit:

// Load the Class. Must use fully qualified name here!
Class clazz = Class.forName("com.crossedstreams.thingy.Foo");

// I need an array as follows to describe the signature
Class[] parameters = new Class[] {String.class, String.class};

// Now I can get a reference to the right constructor
Constructor constructor = clazz.getConstructor(parameters);

// And I can use that Constructor to instantiate the class
Object o = constructor.newInstance(new Object[] {"one", "two"});

// To prove it's really there...
System.out.println(o);

Sortie:

com.crossedstreams.thingy.Foo@20cf2c80

Il ya beaucoup de ressources là-bas qui aller plus dans les détails à ce sujet, et vous devez être conscient que vous êtes en introduisant une dépendance que le compilateur ne peut pas vérifier pour vous - si vous avez mal orthographié le nom de la classe ou de quoi que ce soit, ce sera un échec lors de l'exécution. Aussi, il y a assez peu de types différents d'Exception qui pourrait être lancers au cours de ce processus. C'est une technique très puissante si.

2voto

CodeGoat Points 552

Cela devrait fonctionner:

 import java.lang.reflect.*;

FirstArgType arg1;
SecondArgType arg2;
Class cl = Class.forName("TheClassName");
Constructor con = cl.getConstructor(FirstArgType.class, SecondArgType.class);
Object obj = con.newInstance(arg1, arg2);
 

De là, vous pouvez lancer un type connu.

2voto

Ragdata Points 21

Cela a fonctionné un peu plus proprement pour moi dans JDK7, même si les réponses ci-dessus fait les choses un peu plus difficile que ce qu'ils devaient être à partir d'un newbie point de vue suppose que vous avez déclaré 'className' comme une variable Chaîne de caractères passée en paramètre de méthode ou plus tôt dans la méthode à l'aide de ce code):

Class<?> panel = Class.forName( className );
JPanel newScreen = (JPanel) panel.newInstance();

À partir de ce point vous pouvez utiliser les propriétés / méthodes à partir de votre dynamique de la classe nommée exactement comme vous vous attendez à être en mesure de les utiliser:

JFrame frame = new JFrame(); // <<< Just so no-one gets lost here
frame.getContentPane().removeAll();
frame.getContentPane().add( newScreen );
frame.validate();
frame.repaint();

Les exemples dans d'autres réponses ci-dessus a permis d'erreurs quand j'ai essayé de le faire .add() de la nouvelle "Objet" type d'objet à l'image. La technique décrite ici, m'a donné un objet utilisable avec juste ces 2 lignes de code ci-dessus.

Pas exactement pourquoi certaines que c'était - je suis un Java débutant moi-même.

0voto

rodrigoap Points 4755

Un autre:

 import java.lang.reflect.Constructor;

public class Test {

 public Test(String name) {
	this.name = name;
 }

 public String getName() {
	return name;
 }

 public String toString() {
	return this.name;
 }

 private String name;

 public static void main(String[] args) throws Exception {
	String className = "Test";
	Class clazz = Class.forName(className);
	Constructor tc = clazz.getConstructor(String.class);
	Object t = tc.newInstance("John");
	System.out.println(t);
 }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X