OVH Cloud OVH Cloud

Question simple: méthode courante.

16 réponses
Avatar
hervé dubuis
Bonsoir,

Question toute bête! Comment savoir dans quelle méthode se trouve le
code qui est exécuté.
J'arrive à récupérer la classe courante: this.toString() mais je ne
trouve pas le moyen de connaître la méthode courante.

Merci d'avance.
Hervé.

10 réponses

1 2
Avatar
Laurent Bossavit
J'arrive à récupérer la classe courante: this.toString() mais je ne
trouve pas le moyen de connaître la méthode courante.


Voici un point de départ:

String stackTrace = new Exception().getStackTrace();

Ensuite, concasser la chaîne avec une grosse expression régulière.

Pardonne-moi d'être curieux: à quoi ça va te servir ?

Laurent
http://bossavit.com/
http://bossavit.com/thoughts/

Avatar
hervé dubuis
Laurent Bossavit wrote:

J'arrive à récupérer la classe courante: this.toString() mais je ne
trouve pas le moyen de connaître la méthode courante.



Voici un point de départ:

String stackTrace = new Exception().getStackTrace();

Ensuite, concasser la chaîne avec une grosse expression régulière.

Pardonne-moi d'être curieux: à quoi ça va te servir ?

Laurent
http://bossavit.com/
http://bossavit.com/thoughts/



C pour les messages de log de mon appli. Je voulais pas écrire en dure
le nom de la méthode qui envoie le message car ca peut changer dans le
temps.

Voilà donc la méthode à appeler sous la forme: getCurrentMethod(new
Exception())

private String getCurrentMethod(Exception e)
{
String methodStr = e.getStackTrace()[0].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}


Autre question u peu particulière:
----------------------------------

Soit le code suivant (pas fini mais suffisant pour exposer ma question):

class Scheduler
{
Vector vector;
Log log;
int i;

Scheduler(Log log)
{
this.log = log;
log.add("Scheduler instanciated");
vector = new Vector();
}

//--- ajoute une classe à instancier toutes les
// X millisecondes.
public void add(String classStr, long frequency)
{
vector.add(classStr);
vector.add(frequency);
}

public go()
{
for(i=0;i<vector.size();i=i+2)
{
Class.forName( ((String)vector.get(i))).newInstance();
}
}
}


Question: Comment faire pour passer de manière transparente à la méthode
add les paramètres qui seront à donner à la classe qui sera à instancier?

Merci d'avance.


Avatar
Nicolas Delsaux
Le 13.01 2004, hervé dubuis s'est levé et s'est dit : "tiens, si
j'écrivais aux mecs de fr.comp.lang.java ?"

C pour les messages de log de mon appli. Je voulais pas écrire en dure
le nom de la méthode qui envoie le message car ca peut changer dans le
temps.


Avec log4j, tu fais ça facilement à grand coups de logger.info("mon
message", new Exception()) qui t'imprime non seulement la méthode
courante, mais aussi la pile d'appel qui t'y a mené.

Voilà donc la méthode à appeler sous la forme: getCurrentMethod(new
Exception())

private String getCurrentMethod(Exception e)
{
String methodStr = e.getStackTrace()[0].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}

Tu devrais sans doute garder les paramètres de la méthode, car sans eux,

tu seras bien embêté pour les redéfinitions.

Autre question u peu particulière:
----------------------------------

Soit le code suivant (pas fini mais suffisant pour exposer ma
question):

class Scheduler
{
Vector vector;
Log log;
int i;

Scheduler(Log log)
{
this.log = log;
log.add("Scheduler instanciated");
vector = new Vector();
}



Ouch ! tu utilises des Vector ? Et tu n'as pas mal ? Depuis Java2, il
convient de les remplacer, autant que possible, par des collections
diverses. Consultes le poackage java.util pour y trouver la plus
adaptée.

//--- ajoute une classe à instancier toutes les
// X millisecondes.
public void add(String classStr, long frequency)
{
vector.add(classStr);
vector.add(frequency);
}

public go()
{
for(i=0;i<vector.size();i=i+2)
{
Class.forName(
((String)vector.get(i))).newInstance();
}
}
}


Question: Comment faire pour passer de manière transparente à la
méthode add les paramètres qui seront à donner à la classe qui sera à
instancier?


Tu passes à un tableau d'Object, et, grâce au package java.lang.reflect,
dont je t'invite à consulter la doc, tu pourras choisir dynamiquement le
constructeur à invoquer. Méfiance toutefois : ce genre de code est
excessivement dangereux. Je suis bien curieux de savoir à quoi ça va te
servir ...

Merci d'avance.







--
Nicolas Delsaux
"On a tous entendu qu'un million de singes tapant sur un million de
claviers pourraient produire les oeuvres complètes de Shakespeare.
Maintenant, grâce à Internet, on sait que ça n'est pas vrai." Robert
Wilensky

Avatar
Pierre Crescenzo
Bonjour,

Ouch ! tu utilises des Vector ? Et tu n'as pas mal ? Depuis Java2, il
convient de les remplacer, autant que possible, par des collections
diverses. Consultes le poackage java.util pour y trouver la plus
adaptée.


Où avez-vous eu cette information ? (C'est une vraie question, pas une
contradiction. :-))

En lisant la page
<http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html>, je ne
vois rien de conseillé en ce sens (au contraire, Vector paraît avoir été
réécrite) et la classe ne me semble même pas marquée "deprecated"...

Merci.

[CITATION ALÉATOIRE : Le manque d'argent aidant, je ne dépense
rien. Maurice Roche]

--
Pierre Crescenzo
mailto:
(Retirez « -sansspam » pour répondre. Merci.)
http://www.crescenzo.nom.fr/

Avatar
Nicolas Delsaux
Le 13.01 2004, Pierre Crescenzo s'est levé et s'est dit : "tiens, si
j'écrivais aux mecs de fr.comp.lang.java ?"

Bonjour,

Où avez-vous eu cette information ? (C'est une vraie question, pas une
contradiction. :-))

En lisant la page
<http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html>, je ne
vois rien de conseillé en ce sens (au contraire, Vector paraît avoir été
réécrite) et la classe ne me semble même pas marquée "deprecated"...


Ca n'est pas indiqué dans la doc, puisqu'il ne s'agit pas d'un problème
d'implémentation, mais de design. utiliser des Vector, plutôt que des
Lists, des Sets ou autres collections, c'est se cantonner à une
implémentation, alors qu'en passant par les interfaces associées, il sera
plus facile de faire évoluer le code, mais également de bénéficier de ses
améliorations.
Bref, utiliser Vector, c'est rester en Java 1 alors que Java2 fournit bien
plus de possibilités.

Merci.

[CITATION ALÉATOIRE : Le manque d'argent aidant, je ne dépense
rien. Maurice Roche]




--
Nicolas Delsaux
"S'il existe deux ou plusieurs manières de faire quelque chose et que l'une
de ces manières est susceptible de se solder par une catastrophe, on peut
être certain que quelqu'un se débrouillera pour la choisir."
Edward A.Murphy Jr

Avatar
Richard Delorme
Bonjour,


Ouch ! tu utilises des Vector ? Et tu n'as pas mal ? Depuis Java2, il
convient de les remplacer, autant que possible, par des collections
diverses. Consultes le poackage java.util pour y trouver la plus
adaptée.



Où avez-vous eu cette information ? (C'est une vraie question, pas une
contradiction. :-))

En lisant la page
<http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html>, je ne
vois rien de conseillé en ce sens (au contraire, Vector paraît avoir été
réécrite) et la classe ne me semble même pas marquée "deprecated"...


Elle est redondante avec ArrayList qui est plus rapide que Vector,
essentiellement parce que les méthodes de Vector sont synchronized. De
plus, on peut synchroniser correctement les ArrayList avec la méthode
synchronizedList() de java.util.collection. Il y a donc peu de raison
d'utiliser Vector, hormis la compatibilité avec l'ancien code.

--
Richard


Avatar
vclassine
hervé dubuis wrote in message news:<400341c5$0$24028$...
Laurent Bossavit wrote:

J'arrive à récupérer la classe courante: this.toString() mais je ne
trouve pas le moyen de connaître la méthode courante.



Voici un point de départ:

String stackTrace = new Exception().getStackTrace();

Ensuite, concasser la chaîne avec une grosse expression régulière.

Pardonne-moi d'être curieux: à quoi ça va te servir ?

Laurent
http://bossavit.com/
http://bossavit.com/thoughts/



C pour les messages de log de mon appli. Je voulais pas écrire en dure
le nom de la méthode qui envoie le message car ca peut changer dans le
temps.

Voilà donc la méthode à appeler sous la forme: getCurrentMethod(new
Exception())

private String getCurrentMethod(Exception e)
{
String methodStr = e.getStackTrace()[0].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}


En passant...

private String getCurrentMethod()
{
Exception e = new Exception();
methodStr = e.getStackTrace()[1].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}

C'est moins chiant...
Sinon moi je serais toi je la métrait en static dans une classe Debug,
ou je l'utiliserais directement dans la classe de log.

J'espère que tu compte réserver ça au Debug, parce que ça risque de
faire ramer...



Autre question u peu particulière:
----------------------------------

Soit le code suivant (pas fini mais suffisant pour exposer ma question):

class Scheduler
{
Vector vector;
Log log;
int i;

Scheduler(Log log)
{
this.log = log;
log.add("Scheduler instanciated");
vector = new Vector();
}

//--- ajoute une classe à instancier toutes les
// X millisecondes.
public void add(String classStr, long frequency)
{
vector.add(classStr);
vector.add(frequency);
}

public go()
{
for(i=0;i<vector.size();i=i+2)
{
Class.forName( ((String)vector.get(i))).newInstance();
}
}
}


Question: Comment faire pour passer de manière transparente à la méthode
add les paramètres qui seront à donner à la classe qui sera à instancier?
Je ne sais pas ce que tu veux faire mais ça à l'air louche... :-)




Avatar
hervé dubuis
En passant...

private String getCurrentMethod()
{
Exception e = new Exception();
methodStr = e.getStackTrace()[1].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}


Je ne crois pas que ca marche car si j'instancie l'exception dans la
méthode getCurrentMethod, ce sera ce nom là qu'il va me donner et pas
celui de la méthode appelante.

"Je ne sais pas ce que tu veux faire mais ça à l'air louche..."
--> C tout simple, je voudrais programmer des classes qui
s'exécuteraient à des intervalles de temps régulier.

Et je voudrais que le Scheduler (le plannificateur des tâches) ait une
seule méthode d'ajout de classes (avec passage de paramètres!!!) et pas
une méthode pour chaque type de classe à ajouter.

Avatar
Laurent Bossavit
Et je voudrais que le Scheduler (le plannificateur des tâches) ait une
seule méthode d'ajout de classes (avec passage de paramètres!!!) et pas
une méthode pour chaque type de classe à ajouter.


Donne à ton Scheduler des "fabriques" des objets concernés, au lieu de
t'appuyer sur la magie noire de la reflection. Et évite d'utiliser une
liste linéaire pour stocker des informations hétérogènes "une case sur
deux"; si ces informations ont envie d'aller deux par deux, c'est
qu'elles constituent un type.

interface SchedulableFactory {
public Object /* ou Schedulable */ createInstance();
public int getFrequency();
}

public class Scheduler {

private Vector schedulables;

public void add(SchedulableFactory fact) {
schedulables.add(fact);
}

public void instantiateAll() {
Iterator it = schedulables.iterator();
while(it.hasNext()) {
SchedulableFactory each = (SchedulableFactory)it.next();
each.createInstance();
}
}

}

On peut aussi utiliser la syntaxe (pratique mais pénible à lire) des
classes internes anonymes:

scheduler.add(new SchedulableFactory() {
public Object createInstance() {return new FooBar(true,0,"baz");}
public int getFrequency() { return 10;}
});

Laurent
http://bossavit.com/
http://bossavit.com/thoughts/

Avatar
GLH
avec log4j, tu peux surtout faire ca a grand coup de %M dans le pattern non
?
sans passer une new Exception()

voir a ce sujet la javadoc
http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html

GLH

"Nicolas Delsaux" a écrit dans le message de
news:
Le 13.01 2004, hervé dubuis s'est levé et s'est dit : "tiens, si
j'écrivais aux mecs de fr.comp.lang.java ?"

C pour les messages de log de mon appli. Je voulais pas écrire en dure
le nom de la méthode qui envoie le message car ca peut changer dans le
temps.


Avec log4j, tu fais ça facilement à grand coups de logger.info("mon
message", new Exception()) qui t'imprime non seulement la méthode
courante, mais aussi la pile d'appel qui t'y a mené.

Voilà donc la méthode à appeler sous la forme: getCurrentMethod(new
Exception())

private String getCurrentMethod(Exception e)
{
String methodStr = e.getStackTrace()[0].toString();
methodStr = methodStr.substring(0,methodStr.indexOf('('));
return methodStr;
}

Tu devrais sans doute garder les paramètres de la méthode, car sans eux,

tu seras bien embêté pour les redéfinitions.

Autre question u peu particulière:
----------------------------------

Soit le code suivant (pas fini mais suffisant pour exposer ma
question):

class Scheduler
{
Vector vector;
Log log;
int i;

Scheduler(Log log)
{
this.log = log;
log.add("Scheduler instanciated");
vector = new Vector();
}



Ouch ! tu utilises des Vector ? Et tu n'as pas mal ? Depuis Java2, il
convient de les remplacer, autant que possible, par des collections
diverses. Consultes le poackage java.util pour y trouver la plus
adaptée.

//--- ajoute une classe à instancier toutes les
// X millisecondes.
public void add(String classStr, long frequency)
{
vector.add(classStr);
vector.add(frequency);
}

public go()
{
for(i=0;i<vector.size();i=i+2)
{
Class.forName(
((String)vector.get(i))).newInstance();
}
}
}


Question: Comment faire pour passer de manière transparente à la
méthode add les paramètres qui seront à donner à la classe qui sera à
instancier?


Tu passes à un tableau d'Object, et, grâce au package java.lang.reflect,
dont je t'invite à consulter la doc, tu pourras choisir dynamiquement le
constructeur à invoquer. Méfiance toutefois : ce genre de code est
excessivement dangereux. Je suis bien curieux de savoir à quoi ça va te
servir ...

Merci d'avance.







--
Nicolas Delsaux
"On a tous entendu qu'un million de singes tapant sur un million de
claviers pourraient produire les oeuvres complètes de Shakespeare.
Maintenant, grâce à Internet, on sait que ça n'est pas vrai." Robert
Wilensky



1 2