Question sur java reflection [Résolu]

Signaler
Messages postés
8
Date d'inscription
vendredi 28 novembre 2014
Statut
Membre
Dernière intervention
29 avril 2015
-
Messages postés
8
Date d'inscription
vendredi 28 novembre 2014
Statut
Membre
Dernière intervention
29 avril 2015
-
Bonjour,
je travaille sur java reflection, alors par quelle methode peut-on affichertoutes les classes qui héritent d'une classe mère.
cad :
abstract class A {}
class B extends A{}
class C extends A {}.

Question: comment à partir de A je peux savoir que j'ai deux classes qui héritent de A.?
Merci de m'aider à trouver

3 réponses

Messages postés
5363
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
30 avril 2021
110
Salut,

Depuis B et/ou C savoir que tu hérites de A c'est possible mais depuis A uniquement et sans jamais toucher à B et C, je ne vois pas comment tu peux savoir qui en hérite.

Par contre en listant les classes d'un packages tu peux connaitre qui hérite de qui:

Fichier A.java du package org.test
package org.test;

abstract class A { }

Fichier B.java du package org.test
package org.test;

public class B extends A{ }

Fichier C.java du package org.test
package org.test;

public class C extends A{ }


Fichier Reflect.java
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class Reflect {

  public static void main(final String[] args) throws Exception{
    Class<?>[] classes = getPackageClasses("org.test");
    for(Class<?> c : classes) {
      System.out.println(c);
      System.out.println(" --> " + c.getSuperclass());
    }
  }

  private static Class<?>[] getPackageClasses(final String packageName)
      throws ClassNotFoundException, IOException {
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    final Enumeration<URL> resources = classLoader.getResources(packageName.replace('.', '/'));
    final List<File> dirs = new ArrayList<File>();
    
    while (resources.hasMoreElements())
      dirs.add(new File(resources.nextElement().getFile()));
    
    final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
    for (final File directory : dirs)
      classes.addAll(findClasses(directory, packageName));
    return classes.toArray(new Class<?>[classes.size()]);
  }

  private static List<Class<?>> findClasses(final File root,
      final String packageName) throws ClassNotFoundException {
    final List<Class<?>> classes = new ArrayList<Class<?>>();
    if (!root.exists()) return classes;
    for (final File file : root.listFiles()) {
      if (file.isDirectory()) {
        classes.addAll(findClasses(file, packageName + "." + file.getName()));
      } else if (("" + file).endsWith(".class")) {
        classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
      }
    }
    return classes;
  }
}


De là tu peux facilement déterminer la liste des enfants de A.
Tu peux également étendre le code pour connaitre la liste des classes qui sont chargées par le ClassLoader.


Messages postés
8
Date d'inscription
vendredi 28 novembre 2014
Statut
Membre
Dernière intervention
29 avril 2015

Merci pour tes lignes de codes, qui m on bien aider à simplifier le problème, du coup je fais une fonction getClassesFilles en partant de ta logique qui m'affiche pour chaque classes le classe fille et le nombre de classe fille et ça marche.



voici la fonction
 private static Class<?>[] getClassesFilles(Class<?>[] cls, Class<?> cl){
   final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
   
   for(int i = 0; i< cls.length; i++ ){
    Class parent = cls[i];
    if(parent.getSuperclass()==cl){
     classes.add(parent);
    } 
   }
   return classes.toArray(new Class<?>[classes.size()]);
  }


et le j'appelle dans main
  public static void main(final String[] args) throws Exception{
    Class<?>[] classes = getPackageClasses("org.test");
    for(Class<?> c : classes) {
      System.out.println(c);
      System.out.println(" --> " + c.getSuperclass());
    }
    System.out.println("\n############################ les classes avec les classes qui hérentent d elles##############\n");
    for(int i = 0; i< classes.length;i++){
     Class<?>[] classFilles = getClassesFilles(classes, classes[i]);
     String str = (classFilles.length>1)?"s":"";
     System.out.println("la classe : "+classes[i]+" a : "+classFilles.length+" classe"+str+" fille"+str);
     if(classFilles.length>0){
      for(Class elt : classFilles){
       System.out.println(elt.getName());
      }
      System.out.println();
     }
    }
  }

il marche
Merci et bonne journée


EDIT-Twinuts: Ajout des balises code
Messages postés
5363
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
30 avril 2021
110
de rien,

apres si on reprend le sujet initial et les codes ci-dessus tu obtiens :
public class Reflect {

  public static void main(final String[] args) throws Exception {
    final Class<?>[] derived = getDerivedClasses(org.test.A.class);
    System.out.println("The class A has " + derived.length + " derived classes :");
    for (final Class<?> c : derived) System.out.println(" --> " + c);
  }

  private static Class<?>[] getDerivedClasses(final Class<?> cl) throws ClassNotFoundException, IOException {
    final Class<?>[] classes = getPackageClasses(cl.getPackage().getName());
    final List<Class<?>> derived = new ArrayList<Class<?>>();
    for (final Class<?> c : classes) {
      if (c.getSuperclass().equals(cl))
        derived.add(c);
    }
    return derived.toArray(new Class<?>[derived.size()]);
  }
.........
}


Ce qui te permet à partir de A de savoir qui en hérite (à améliorer si tu veux connaitre cette information depuis le ClassLoader)
Messages postés
8
Date d'inscription
vendredi 28 novembre 2014
Statut
Membre
Dernière intervention
29 avril 2015

oui c'est ça