Automatisch ausgeführter Code

Moin,

ich habe eine Frage an die Java Gurus hier. Vielleicht könnt ihr mir weiterhelfen? Ich nenne einfach mal ein einfaches Beispiel:

Ich habe eine Klasse Klasse1:

public abstract class Klasse1{
public void callAlways(){
…code…
}
}

Davon abgeleitet die Klasse2

public class Klasse2 extends Klasse1{
public void methode1(){
…code…
}
}

Wenn ich nun aus einer dritten Klasse:

public class Klasse3{
…code…
klasse2 k2=new Klasse2();
k2.methode1();
…code…
}

die Methode methode1() aus der Klasse2 aufrufe soll zunächst die methode callAlways() aufgerufen werden. Und zwar ohne sie explizit in der Klasse3 bzw. der methode1 aus Klasse2 zu nennen. Anders gesagt ich möchte weder sowas:

public class Klasse2 extends Klasse1{
public void methode1{
callAlways();
…code…
}
}

noch so was:

public class Klasse3{
…code…
klasse2 k2=new Klasse2();
k2.callAlways();
k2.methode1();
…code…
}

geht das? Gibt es eine Möglichkeit die Methode callAlways() VOR jedem Methodenaufruf der Klasse2 auszuführen, auch wenn mir zur Zeit der implementation nicht bekannt ist welche Methoden die oben genannte Klasse2 hinterher konkret hat?

Wär schön wenn ihr mir weiterhelfen könnt oder definitiv sagen könnt ob es nicht so geht wie ich mir das vorstelle.

Danke

Michael

Hallo.

Java Gurus hier.

Hält sich in Grenzen :wink:
(…)

Gibt es eine Möglichkeit die Methode callAlways()
VOR jedem Methodenaufruf der Klasse2 auszuführen, auch wenn
mir zur Zeit der implementation nicht bekannt ist welche
Methoden die oben genannte Klasse2 hinterher konkret hat?

Ein Stichwort wäre ‚static‘: damit kann man eine Methode unabhängig von ohrer Herkunftsklasse aufrufen.
Aber ob ‚Reflection‘ hier wirklich hilft ? http://www.computerbase.de/lexikon/Reflexion_%28Prog…

mfg M.L.

Hey M.L.

Reflection hab ich schon durch. Mehrere Bücher und google befragt. Hilft mir aber auch nicht wirklich weiter, weil ich damit zwar rausfinde was eine Klasse für Methoden und Attribute anbietet, aber nicht wann diese aufgerufen werden.
Der static-Block hilft nicht. Dieser wird nur einmal beim laden der Klasse aufgerufen. Die anonyme Methode ohne jeglichen Methodennamen, die bei Initialisierung der Klasse jeweils aufgerufen wird auch nicht. Gibt es so was für Methoden? Ich glaub es nähmlich nicht.

Michael

Hallo,
ich hab mir dazu ja schon vorher ein paar Gedanken gemacht und wollte noch mal nachhaken. Mit Hilfe der Reflection könnte ich die einzelnen Methoden der Klasse2 indirekt über eine Methode der Oberklasse Klasse1 aufrufen. Das könnte dann in etwa so aussehen:

public abstract class Klasse1{
public static Object call(String method, Object [] params){
this.getClass().getMethod(method,params).invoke(this,params);
}
}

(das funktioniert so nicht, soll auch nur verdeutlichen wie ich es meine :smile:)

der Aufruf der methode1 sähe dann so aus:

k2.call(„methode2“,params);

das hat, abgesehen davon, dass es nicht sehr schön ist, zwei riesen Nachteile: ich müsste zunächst die einzelnen Parameter in den entsprechend verlangten Typ casten
und dann den rückgabewert ebenso…
gefällt mir nicht!

Lässt sich da mehr rausholen?

Michael

Moien

Lässt sich da mehr rausholen?

Ja, aber nur wenn du versprichst das nächste Mal PRE-Tags zur besseren Lesbarkeit einzusetzen.

Du willst ja an sich die Klasse2 mit protokollieren, ohne aber Klasse2 substanziell zu ändern. Wenn man aus Klasse2 ein Interface ziehen kann geht das relativ einfach, und zwar über java.lang.reflect.Proxy. Man muss dann allerdings alle new Klasse1/2 auf new Proxy umcoden (factory-pattern ?).

Wenn es etwas komplexer sein darf (und du vollständige Kontrolle über die JVM hast): http://java.sun.com/products/jpda/ Damit kann man fast alles was die sun-JVM tut mitschreiben. Dann muss man nix ändern.

cu

1 Like

Hey,

Ja, aber nur wenn du versprichst das nächste Mal PRE-Tags zur
besseren Lesbarkeit einzusetzen.

Versprochen!

Du willst ja an sich die Klasse2 mit protokollieren, ohne aber
Klasse2 substanziell zu ändern. Wenn man aus Klasse2 ein
Interface ziehen kann geht das relativ einfach, und zwar über
java.lang.reflect.Proxy. Man muss dann allerdings alle new
Klasse1/2 auf new Proxy umcoden (factory-pattern ?).

Das hab ich auch schon angeguckt hilft mir aber leider nicht viel weiter (glaube ich zumindest jetzt gerade). Werds mir morgen noch mal ansehen.

Wenn es etwas komplexer sein darf (und du vollständige
Kontrolle über die JVM hast):
http://java.sun.com/products/jpda/ Damit kann man fast alles
was die sun-JVM tut mitschreiben. Dann muss man nix ändern.

Du wirst lachen ich bin heute abend nach längerem Suchen auf das Java Debug Interface (JDI) gestoßen und war gerade dabei mir einen Überblick zu verschaffen.
Kennst du dich ein wenig damit aus? So wie ich das verstanden habe, wird für das Debugging extra eine VM gestartet. Ist das richtig? Verlangsamt das nicht alles? Oder hab ich da noch was garnicht verstanden? Dann entschuldige diese Schnellschussfrage hab das ganze heute abend nur mal schnell überflogen :smile:

Danke erst mal für die erste Antwort

Michael

Moin, moin,

was Du suchst kannst Du mittel AOP lösen.
Entweder mittels Google „aspect java“ oder direkt:

Wenn Du mit Eclipse entwickelst, dann ist evtl. noch http://www.eclipse.org/aspectj/ interessant.

Gruß,
Frank

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hey Frank,

sorry bin heute erst wieder dazu gekommen mich mit dem Programm zu beschäftigen.
AOP war das was ich gesucht hab. Im ersten Moment gewöhnungsbedürftig, aber wenn man sich eingelebt hat relativ simpel.
Zumindest nicht ganz so aufwändig wie das JDI :smile:
Das gibt einen Stern.
Thx!

Michael