IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Nom de la class depuis le main


Sujet :

Langage Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut Nom de la class depuis le main
    Comment trouver le nom de la class que l'on exécute dans le main ?

    Pour info, je désire faire une class abstraite qui s'instantie elle-même dans son propre main par reflexion, pour cela j'ai besoin de son nom. L'objectif étant de faire des classes filles qui l'étendent et ne possède que le code de la méthode doit().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public abstract class A {
     public static void main(String args[]) {
    	String className = donnelenomdelaclass(); // retourne le nom de la classe
    	Class aClass = Class.forName(className);
    	Object instance = aClass.newInstance();
            instance.doit()
     }
     public abstract doit()
    } 
     
    public class B {
     public doit() {
       // mon code;
     }
    }
    J'ai bien penser à définir en dur le nom de la class puis utiliser l'héritage mais l'héritage d'attribut ou de méthode statique est impossible (le main est statique et ne peux utiliser que des attribut statique)

  2. #2
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    C'est étrange ce que tu veux faire...

    Pourquoi as-tu besoin de faire cela?

  3. #3
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Throwable t = new Throwable();
    StackTraceElement directCaller = t.getStackTrace()[1];
    directCaller.getClassName();
    Je n'ai pas tester mais un truc dans ce genre devrait marcher.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Par défaut
    Ouah. Bien joué !
    Faute de frappe : remplacer le 1 par 0 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String className = new Throwable().getStackTrace()[0].getClassName();
    Nicolas

  5. #5
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Faut pas abuser, une exception pour faire ça, c'est pas correct !!!

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut Pourquoi
    Je veux faire cela car j'ai un framework qui isole la gestion transactionnelle et je suis obligé pour cela de lui passer une instance en paramètre depuis le main.

    Le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    String className = new Throwable().getStackTrace()[0].getClassName();
    Renvoie bien le nom de la classe mais toujours celui de la super classe (voir mon exemple plus haut).

    En fait je pense que l'héritage dans ce cas (utilisation du main "statique" de la super class) est impossible. Je m'explique : Lors que l'on exécute la classe B (enfant), on exécute le main de la classe A (parent). Dans ce main statique il semble impossible d'utiliser l'héritage pour faire référence à la classe enfant exécuté (dans mon cas pour trouver son nom). --> pas d'héritage possible pour une méthode statique ! isn't it ?

    Pour le code *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public abstract class A {
     public static void main(String args[]) {
    	String className = new Throwable().getStackTrace()[0].getClassName();
    System.out.println("=====> className ="+className );
     }
     public abstract doit()
    } 
     
    public class B {
     public doit() {
       // mon code;
     }
    public class C {
     public doit() {
       // mon code;
     }
    Que l'on lance la class B ou la class C le "className" sera toujours A.

    En conclusion, je suis marond sur ce coup, non ?

  7. #7
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    Moi, je crois savoir ce que tu veux faire mais ça ne marchera pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public abstract class A {
     public static void main(String args[]) {
    	String className = new Throwable().getStackTrace()[0].getClassName();
     
            // className vaut A et comme elle est abstraite, elle ne peut être instanciée !
     
     
            Class aClass = Class.forName(className);
    	Object instance = aClass.newInstance();
            instance.doit()
     }
     public abstract doit()
    }
    Quand à B, s'il n'a pas de main, il appellera celui de son parent mais dans le parent, tu n'as pas le nom de "B" et je ne sais pas comment tu pourrais l'avoir ?

  8. #8
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    Comme tu dis, j'ai bien peur que tu sois marond sur ce coup là ...

    C'est bête, c'était bien vu ...

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut
    J'ai bien mis la classe A "abtraite" justement pour ne pas pouvoir l'instancier mais juste bénéficier de son main par héritage.

    Ma solution : Je vais faire du copier/coller du main de la super classe (A) pour les classes enfant (B et C) et ne pas faire d'héritage

    Merci de vos réponses éclairées.

  10. #10
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    Si tu crées un main dans chaque classe (ce qu'on voulait éviter au départ), autant faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public static void main(String args[])
    {
            new B().doit()
    }
     
    public static void main(String args[])
    {
            new C().doit()
    }

  11. #11
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Une méthode statique n'est pas "héritée", on peut l'appeler par héritage mais elle est quand meme associée à la classe mère...

  12. #12
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par ®om
    Une méthode statique n'est pas "héritée", on peut l'appeler par héritage mais elle est quand meme associée à la classe mère...
    On ne peut pas l'appeler par héritage : c'est juste le compilateur qui "corrige" cela à la compilation : c'est un accès indirect aux membres statiques...


    Dans ton cas, je suppose que tu voudrais avoir un traitement plus long dans ton main(). La meilleure solution serait d'utiliser une autre méthode statique qui se chargerait de tout, et qui sera simplement appeler par la méthode main() de tes classes filles, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public abstract class A {
     
    	/**
             * Crée et exécute la classe.
             * @param type Le type exact.
             */
    	public static void launch(Class<? extends A> type) {
    		try {
    			A instance = type.newInstance();
    			instance.doit();
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
     
    	public abstract void doit();
    }
    Ainsi lorsque tu hérites il suffit de redéfinir les méthodes et d'appeler A.launch() dans le main() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class B extends A {
     
    	@Override
    	public void doit() {
    		System.out.println("Hello World !");
    	}
     
    	public static void main(String[] args) {
    		A.launch(B.class);
    	}
    }

    Cette solution est largement inspiré de ce qui est fait dans l'Application Framework pour Swing

    a++

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut
    Merci adiGuba,

    cette solution s'avère payante et je peux "factoriser" mon code dans ma super classe à moindre coup !

  14. #14
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Citation Envoyé par ®om
    Faut pas abuser, une exception pour faire ça, c'est pas correct !!!
    Le use case mis à part, as tu une meilleure solution pour connaire la classe qui a appellé la méthode courante ?
    En plus je vois pas bien le problème, la stack est de toutes facons maintenue constamment par la VM donc je ne vois pas de problème de perf inhérent.

  15. #15
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par zekey
    Le use case mis à part, as tu une meilleure solution pour connaire la classe qui a appellé la méthode courante ?
    En plus je vois pas bien le problème, la stack est de toutes facons maintenue constamment par la VM donc je ne vois pas de problème de perf inhérent.
    Le cout de génération du stack est quand même couteux...
    S'il n'est fait qu'une seule fois c'est bien sûr insignifiant, mais s'il est généré plusieurs fois cela peut avoir un impact.

    Maintenant c'est sûr qu'il n'existe aucune autre solution pour ce cas précis...

    a++

  16. #16
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Citation Envoyé par adiGuba
    Le cout de génération du stack est quand même couteux...
    S'il n'est fait qu'une seule fois c'est bien sûr insignifiant, mais s'il est généré plusieurs fois cela peut avoir un impact.

    Maintenant c'est sûr qu'il n'existe aucune autre solution pour ce cas précis...

    a++
    Ce qui m'embête c'est que je ne vois pas pourquoi la génération de la stack serait couteuse. La stack doit être maintenue quoi qu'il en soit. Faudrait que je regarde exactement ce que ca coute.

  17. #17
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par zekey
    Le use case mis à part, as tu une meilleure solution pour connaire la classe qui a appellé la méthode courante ?
    En plus je vois pas bien le problème, la stack est de toutes facons maintenue constamment par la VM donc je ne vois pas de problème de perf inhérent.
    Tu n'as jamais à connaitre l'objet/la classe qui t'a appelée, ou alors c'est donné en paramètre... Sinon il y a un problème de conception qq part

  18. #18
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Citation Envoyé par ®om
    Tu n'as jamais à connaitre l'objet/la classe qui t'a appelée, ou alors c'est donné en paramètre... Sinon il y a un problème de conception qq part
    A non c'est un peu court jeune homme, on aurait pu dire bien des choses en somme....

    Un use case pas si crétin, le cas des logs.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private static Logger myLogger = LoggerFactory.getLogger(Myclass.class);
    Dans ce cas je me vois plutot faire une classe avec une méthode Trace statique
    qui utilise le bout de code en haut pour utiliser le bon logger.
    Mais surtout dans le cas des logs il faudrait être sur de l'impact sur les perfs.
    Je m'en vais voire ce que donne la version 5 ou 6 avec ce genre de trucs louches.

  19. #19
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par zekey
    A non c'est un peu court jeune homme, on aurait pu dire bien des choses en somme....

    Un use case pas si crétin, le cas des logs.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private static Logger myLogger = LoggerFactory.getLogger(Myclass.class);
    Dans ce cas je me vois plutot faire une classe avec une méthode Trace statique
    qui utilise le bout de code en haut pour utiliser le bon logger.
    Mais surtout dans le cas des logs il faudrait être sur de l'impact sur les perfs.
    Je m'en vais voire ce que donne la version 5 ou 6 avec ce genre de trucs louches.
    J'ai bien précisé "ou alors c'est donnée en paramètre", c'est exactement ce que tu fais en faisant Myclass.class.

  20. #20
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Citation Envoyé par ®om
    J'ai bien précisé "ou alors c'est donnée en paramètre", c'est exactement ce que tu fais en faisant Myclass.class.

    Pour info je viens de tester sur 500'000 logs et la différence est de 5 secondes pour le jdk 5.0. Soit un ralentissement de 10%.
    Même résultat avec le JDK 6 si ce n'est que le programme va 10% plus vite.

    Bon une seconde pour 100'000 logs ce n'est pas anodin mais bon c'est pas la mort non plus surtout dans le cas d'une application interactive.

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/07/2009, 09h45
  2. Réponses: 0
    Dernier message: 29/01/2009, 10h43
  3. Réponses: 7
    Dernier message: 08/01/2007, 12h11
  4. Réponses: 11
    Dernier message: 16/10/2004, 18h14
  5. [tomcat]chargement dynamique de classes depuis une webapp
    Par alphamax dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 12/03/2004, 09h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo