Newsgroup: it.comp.java
Titolo: chi ha chiamato il metodo?

Ciao a tutti, non so se è possibile, ma vorrei sapere in automatico,
quindi senza paramentri, la classe o l'oggetto che richiama un metodo.
Sostanzialmente una cosa del genere:
Ho una classe C1 con dei metodi public static.
Un'altra classe C2 invoca uno dei metodi di C1, per esempio m1.
Ora vorrei poter sapere all'interno del metodo m1, qual'è stata la
classe ad invocarlo.
Si puo' fare?
Ricordo (1998) che in Delphi esisteva l'oggetto Sender, esiste una cosa
analoga in Java?
La JDK è la 1 e mezzo!
Ciao e grazie a tutti per eventuali risposte, Himgi.

 quindi senza paramentri, la classe o l'oggetto che richiama un metodo.
In Java non c'e un metodo "standard".
Quello che e' gia' stato suggerito in questo ng e' quello di gettare 
un'exception, "catcharla" subito e analizzare la stacktrace.
-- 
Giambo - Occhio al filtro antispam _e_ alla whitelist !

Sì, infatti è quello che ho trovato in giro sui vari forum e NG
internazionali.
A questo punto l'unico modo più pulito è quello di passare il
className come argomento al metodo.
Ciao, e grazie, Himgi.
Giambo ha scritto:


himgi ha scritto:

Ok...
Ho seguito la strada dello stack trace!
Non è pulito ma efficace.
Sostanzialmente si tratta di:
 - creare un'eccezione
 - lanciarla
 - catcharla
 - prendo l'array di StackTraceElement dal thread corrente
 - salto i primi che sono di sistema e della mia classe
 - quello subito dopo è la classe che ha invocato il metodo
Scusate i neologismi tecnici in inglesi tradotti in italiano! :D
Ora il
codice............................................................ :D
public class MiaClasse {
public static void mioMetodo(Miei parametri) {
		String senderClass = null;
		String senderMethod = null;
		Exception _ex = new NullPointerException("");
		try {
			throw _ex;
		} catch (Exception e) {
			StackTraceElement[] stes = Thread.currentThread().getStackTrace();
			for (int i=0; i<stes.length; i++) {
				StackTraceElement ste = stes[i];
				if (ste.getClassName() != MiaClasse.class.getName() &&
					ste.getFileName() != null && ste.getLineNumber() > 0) {
					senderClass = ste.getClassName();
					senderMethod = ste.getMethodName();
					break;
				}
			}
		}
}
}
Se pò servì!!!
;)
Himgi

 ste.getClassName() != MiaClasse.class.getName() 
ma cosi':
! ste.getClassName().equals(MiaClasse.class.getName())

> ste.getClassName() != MiaClasse.class.getName()
m> ma cosi':
m> ! ste.getClassName().equals(MiaClasse.class.getName())
Dice il saggio:
"La cosa è che potlebbe pelsino "funzionale" ! :> :> :>
 Se  non licoldo  male, c'è  un solo  oggetto Class  pel ogni  classe e
 qualcosa mi  dice che facendo lo  stack flame plendono  la stlinca col
 nome della classe ploplio da quell'oggetto (copia di un puntatole).
 E quindi il test potlebbe essele eseguito "collettamente" fintanto che
 non gila su una JVM che  su quel nome esegue qualche opelazione... Con
 la gente che non capisce che cavolo stà capitando.
 E poi pensano che Java sia un linguaggio di ploglammazione semplice!"
                         (者娼 巳版尸, monaco emacsita e programmatore 
                          Java, 700 A.C. - vivente)
-- 
 /\           ___
/___/\_|_|\_|__|___Gian Uberto Lauri_____
  //--\| | \|  |   Integralista GNUslamico
\/                 e coltivatore diretto di Software

 > StackTraceElement[] stes = Thread.currentThread().getStackTrace();
E' che il suggerimento sull'eccezione probabilmente era precedente alla
1.5 la quale ha tirato il metodo getStackTrace da Thread

pio...@inwind.it
 ha scritto:

Rispondo a tutti!
Avete ragione tutti!
L'eccezzione non serve ad una mazza...
Il confornto tra stringhe non si fa con == ma con equals (nel mio caso
IgnoreCase non va bene)...
Grazie a tutti!
Himgi

> }
Ebbene, ero incuriosito dalla cosa e ho voluto provarla.
Utilizzando Thread.currentThread().getStackTrace() non funziona, io ottengo
senderClass=java.lang.Thread
senderMethod=getStackTrace
Con l'altro metodo funziona se l'array di StackTraceElement lo ricavo dall'eccezione stessa ex.getStackTrace().

 Con l'altro metodo funziona se l'array di StackTraceElement lo ricavo dall'eccezione stessa ex.getStackTrace().
uhm.. a quanto pare serve un terzo parere...

 uhm.. a quanto pare serve un terzo parere...
Interessante comportamento ^^;
Io l'ho fatto girare con jre 1.5.0_03-b07
[chiaramente con la versione 1.4.2_08 non c'e' Thread.currentThread().getStackTrace() quindi resta valida la versione col throw/catch e stack trace ricavato dall'eccezione]
Saluti
CarMas



public class Nome {
 
    public Nome() {
    }
 
    public void chiSono() {
        StackTraceElement se[] =  Thread.currentThread().getStackTrace();
        for (int i = 0; i < se.length; i++) {
            System.out.println(i + ": " + se[i].getMethodName());
        }
    }
 
    public static void main(String args[]) {
        Nome m = new Nome();
        m.chiSono();
    }
}
fornisce:
0: dumpThreads
1: getStackTrace
2: chiSono
3: main

In data Mon, 18 Dec 2006 12:26:51 +0100, CarMas ha scritto:

e cosi', che e' la versione originale riadattata al mio ciclo:
 public void chiSono() {
        StackTraceElement se[] =  Thread.currentThread().getStackTrace();
        for (int i = 0; i < se.length; i++) {
            System.out.println(i + ": " + se[i].getMethodName());
 
            if (se[i].getClassName().equals(Nome.class.getName()) &&
                se[i].getFileName() != null && se[i].getLineNumber() > 0) {
                System.err.println(se[i].getClassName() + " " +
se[i].getMethodName());
                break;
            }
        }
    }
fornisce:
testvari.Nome chiSono
quindi funziona, 1.5.0_09

 3: main
Yes, e' lo stesso test che ho fatto io e ho gli stessi risultati.
Se al posto di se[i].getMethodName() metti un piu' banale .toString() ottieni:
0: java.lang.Thread.dumpThreads(Native Method)
1: java.lang.Thread.getStackTrace(Thread.java:1383)
2: Nome.chiSono(Nome.java:7)
3: Nome.main(Nome.java:15)

 quindi funziona, 1.5.0_09
Don't think so.
public class TestEsterno {
    public static void main(String[] args) {
       Nome n=new Nome();
       n.chiSono();
    }
}
Senza not: Nome chiSono
Con il not: java.lang.Thread getStackTrace
Entrambi errati.
Saluti
CarMas

 Entrambi errati.
in effetti non avevo capito un cazzo

 in effetti non avevo capito un cazzo
Io per ora ho risolto cosi', dall'analisi degli stack trace... quando trovo che getClassName() sullo StackTraceElement e' uguale al nome della classe (ho cambiato anche Nome.class.getName() con this.getClass().getName() che mi sembrava piu' bello), allora mi preparo perche' l'elemento successivo e' quello che ha chiamato il metodo.
Ok, e' piu' incasinato da dire che da fare ^^;
Poi lascio a chi e' piu' esperto/ne ha piu' voglia/ha idee migliori la prossima parola ;)
Saluti
CarMas

CarMas ha scritto:

Bravo, la tua soluzione è migliore della via!
Non avevo notato che subito che il getClass().getName() corrispondeva
al nome della mia classe, subito dopo c'era la classe del vero
chiamante.
(Hai ragione è facile a farsi che a dirsi).
Himgi

CarMas ha scritto:

Bravo, la tua soluzione è migliore della mia!
