Andy: Aufrufende Klasse / Objekt finden

Hallo!

Ist mir jetzt spontan eingefallen:
Gibt es (gibt es bestimmt!) eine Möglichkeit in einem Objekt herauszufinden in welcher Klasse bzw. welchem Objekt es instanziert worden ist? Oder wenn eine Methode ausgeführt wird, woher der Aufruf kommt?
Wie schon geschrieben, muss ja gehen (mit Reflection?), da eine Exception ja auch einen kompletten StackTrace liefert!

Also nochmal ein Beispiel:
public class Rufer {
  final static void main (String args[]) {
    Empfaenger e = new Empfaenger();
    e.rufan();
    e.printAnstifter();
  }
}
public class Empfaenger {
  public void rufan() {
    System.out.println ("Ich werde angerufen von "
    getAnrufer());
  }
  public void printAnstifter() {
    System.out.println ("Ich werde instanziert von "
    getErzeuger());
  }

}
Wie müssen getAnrufer() bzw. getErzeuger() ausschauen?

Kann sein das es absolut trivial ist und ich jetzt nur ein Brett vorm Kopf habe?! Oder ist es unmöglich?!

Ciao,
Andy

  1. Hallo,

    Ist mir jetzt spontan eingefallen:
    Gibt es (gibt es bestimmt!) eine Möglichkeit in einem Objekt herauszufinden in welcher Klasse bzw. welchem Objekt es instanziert worden ist? Oder wenn eine Methode ausgeführt wird, woher der Aufruf kommt?
    Wie schon geschrieben, muss ja gehen (mit Reflection?), da eine Exception ja auch einen kompletten StackTrace liefert!

    Damit liegst du schonmal gar nicht so falsch. Um den Aufrufer heraus-
    zufinden, kannst du nämlich eine neue Exception erzeugen, und dann
    den Stacktrace auswerten.
    Wie das geht, ist z.B. in einem der Sun Tech Tips beschrieben.

    Du kriegst allerdings sowohl Klassen- als auch Methodenname nur als
    String heraus, und nicht etwa als Class- oder Method-Objekt. Über
    Reflections sollte es aber ein leichtes sein, diese Objekte zu
    generieren.

    Eine andere Möglichkeit an die aufrufenden Objekte/Methoden zu
    kommen, wird es wohl nicht geben, wenn es sogar Sun über eine
    "künstliche" Exception macht.

    Direkt über Reflections kannst du den Aufrufer wohl nicht herausfinden.
    Beachte, daß viele systemnahe Methoden "native" sind. Z.B. ist die
    Methode Throwable.fillInStackTrace(), die für die Exception
    letztendlich den Stacktrace ermittelt, native. Genauso getStackTrace().

    Gruß
    Slyh

  2. Hallo Andy,

    Gibt es (gibt es bestimmt!) eine Möglichkeit in einem Objekt herauszufinden in welcher Klasse bzw. welchem Objekt es instanziert worden ist?

    Nein gibt es nicht. Die Klasse, von der aus die Instanz erzeugt wurde, spielt hinterher keine besondere Rolle mehr.

    Oder wenn eine Methode ausgeführt wird, woher der Aufruf kommt?

    Ja, das geht.

    Seit 1.5 mit Thread.getCurrent().getStackTrace()
    Für älter JDKs musst Du eine Exception erzeugen und abfangen, dann den StackTrace in einen String schreiben lassen (geht glaube ich nur über einen Writer) und dann parsen.

    Wenn Du nicht gerade ein Werkzeug zur Programmanalyse o.ä. schreiben willst, solltest Du darüber nachdenken, ob Dein Ansatz etwas taugt.
    Wenn Du das Verhalten einer Methode vom aktuellen Stacktrace abhängig machen muss, bist Du mit an Sicherheit grenzender Wahrscheinlichkeit auf dem Holzweg.

    Grüße

    Daniel

    1. Hallo,

      Gibt es (gibt es bestimmt!) eine Möglichkeit in einem Objekt herauszufinden in welcher Klasse bzw. welchem Objekt es instanziert worden ist?
      Nein gibt es nicht. Die Klasse, von der aus die Instanz erzeugt wurde, spielt hinterher keine besondere Rolle mehr.

      Naja, der Konstruktor könnte natürlich den Aufrufer, und damit die
      instanzierende Methode auslesen und merken.

      Seit 1.5 mit Thread.getCurrent().getStackTrace()

      Ach, schau, das wußte ich noch gar nicht.
      Die Methode heißt übrigens "currentThread()", nicht "getCurrent()".

      Für älter JDKs musst Du eine Exception erzeugen und abfangen, dann den StackTrace in einen String schreiben lassen (geht glaube ich nur über einen Writer) und dann parsen.

      Ja, so war das bis JDK 1.3. Für JDK 1.4 gilt "mein" Vorgehen. Für
      JDK 1.5 ist deine Methode wohl die beste.

      Wenn Du das Verhalten einer Methode vom aktuellen Stacktrace abhängig machen muss, bist Du mit an Sicherheit grenzender Wahrscheinlichkeit auf dem Holzweg.

      ACK!

      Gruß
      Slyh

      1. Hallo ihr zwei!

        Seit 1.5 mit Thread.getCurrent().getStackTrace()
        Für älter JDKs musst Du eine Exception erzeugen und abfangen, dann den StackTrace in einen String schreiben lassen (geht glaube ich nur über einen Writer) und dann parsen.
        Ja, so war das bis JDK 1.3. Für JDK 1.4 gilt "mein" Vorgehen. Für
        JDK 1.5 ist deine Methode wohl die beste.

        Das mit der Exception hab ich mir inzwischen auch überlegt gehabt!

        Wenn Du das Verhalten einer Methode vom aktuellen Stacktrace abhängig machen muss, bist Du mit an Sicherheit grenzender Wahrscheinlichkeit auf dem Holzweg.

        Nö, nö, war wie ich eingangs geschrieben hat ein spontaner Einfall. Wollt's halt wissen, denn Wissen ist Macht! Und nun gute Nacht! ;-)

        Ciao,
        Andy