Créer un objet dont on a le nom de la classe objet en String

Fermé
rom650 - 29 mars 2015 à 12:34
 rom650 - 31 mars 2015 à 13:18
Bonjour,

Pour mon école, nous avons un projet d'informatique reposant sur un jeu.
Nous avons un plateau qui génère aléatoirement des types de cases et afin de rendre cela plus facilement modifiable, nous avons créé un fichier texte qui donne le nom de l'objet dans un string (enfin le nom de la classe fille étendue de la classe mère).
Est-il possible d'appeler le constructeur de l'objet dont le nom de ce constructeur est un String. C'est un peu compliquer à vous expliquer. Voici le code pour comprendre.

public void setCasePlateau(casePlateau casePlateau, int type){

String fichier ="typeCase.txt";

//lecture du fichier texte contenant les noms des classes en fonction du type
try{
InputStream ips=new FileInputStream(fichier);
InputStreamReader ipsr=new InputStreamReader(ips);
BufferedReader br=new BufferedReader(ipsr);
String ligne;
String typeString = Integer.toString(type);
String nomClasse;
while ((ligne=br.readLine())!=null){
if(ligne.equals(typeString)){ // Si le type correspond, on regarde le nom de la classe sur la ligne suivante
nomClasse=br.readLine();
System.out.println(nomClasse);
casePlateau = new "nomClasse"(); // mon string est ici, et c'est ici que je voudrais trouver comment faire !!
}
else{ // Sinon, on saute une ligne
br.readLine();
}
}
br.close();
}
catch (Exception e){
System.out.println(e.toString());
}

}




Merci d'avance à tous :)


A voir également:

1 réponse

KX Messages postés 16735 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 17 mai 2024 3 015
29 mars 2015 à 13:31
Bonjour,

"Est-il possible d'appeler le constructeur de l'objet dont le nom de ce constructeur est un String."
Avec de l'introspection c'est possible, mais il faudrait que le constructeur n'ait pas de paramètre, ou qu'ils aient tous les même paramètres en entrée.

String className = "ClasseFille";

Class<ClasseMere> classeMere = (Class<ClasseMere>) Class.forName(className);

// Constructeur sans paramètre
ClasseMere objetMere = classeMere.newInstance();

// Constructeur avec paramètre (Exemple: int=42 et String="toto")
Constructor<ClasseMere> constructor = classeMere.getConstructor(int.class, String.class);
ClasseMere objetMere = constructor.newInstance(42, "toto");

Remarque : formellement le constructeur n'est pas celui de la classe mère, mais celui de la classe fille qui sera récupéré. Cependant au niveau des classes de manipulation on peut y faire abstraction grâce à l'héritage.
0
KX Messages postés 16735 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 17 mai 2024 3 015
29 mars 2015 à 14:40
Remarque : concernant le reste de ton code, je te conseilles d'utiliser la classe Scanner pour lire un fichier, c'est plus simple que la combinaison d'InputStream que tu fais.

De plus, je te déconseilles vivement de catcher une Exception par un System.err.println, car ça ne te donnera pas le détail de l'erreur (quelle ligne ça planté par exemple), il vaut donc mieux faire un printStackTrace

Il faudrait également penser à découper ton code en méthode, par exemple il n'y a pas de raison que la lecture du fichier se fasse au moment du setteur, il serait plus logique de lire une seule fois le fichier et de stocker ses différentes valeurs dans une Map.

private static final String FILE = "typeCase.txt";
private static final Class<?>[] CONSTRUCTOR_PARAMETERS_TYPES = { int.class, String.class };
private static final Object[] CONSTRUCTOR_INIT_PARAMETERS = { 42, "toto" };

private static final Map<Integer, Constructor<?>> CONSTRUCTORS_BY_TYPE = loadFile(FILE, CONSTRUCTOR_PARAMETERS_TYPES);

private static Map<Integer, Constructor<?>> loadFile(String fileName, Class<?>... parametersTypes) {

    Map<Integer, Constructor<?>> result = new TreeMap<Integer, Constructor<?>>();

    Scanner sc = null;

    try {
        sc = new Scanner(fileName);

        while (sc.hasNextLine()) {
            Integer type = null;
            Constructor<?> constructor = null;

            try {
                String line = sc.nextLine();
                type = Integer.parseInt(line);
            } catch (Exception e) {
                System.err.println("Can't read the type: " + type);
                e.printStackTrace();
                continue;
            }

            if (!sc.hasNextLine()) {
                System.err.println("Unexpected end of file for type: " + type);
                break;
            }

            try {
                String line = sc.nextLine();
                Class<?> clazz = Class.forName(line);
                constructor = clazz.getConstructor(parametersTypes);
            } catch (Exception e) {
                System.err.println("No constructor loadable for type: " + type);
                e.printStackTrace();
                continue;
            }

            result.put(type, constructor);
        }
    } catch (RuntimeException e) {
        e.printStackTrace();
    } finally {
        if (sc != null) {
            try {
                sc.close();
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
    }

    return result;
}

public void setCasePlateau(int type) {

    Constructor<?> constructor = CONSTRUCTORS_BY_TYPE.get(type);

    if (constructor != null) {
        try {
            this.casePlateau = (CasePlateau) constructor.newInstance(CONSTRUCTOR_INIT_PARAMETERS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        System.err.println("No constructor loaded for type: " + type);
    }
}
0
Merci beaucoup !
Je teste ça !!!
0