Hier ist ein Beispielcode, mit dem Sie beginnen können:
import java.util.*;// An interface to be implemented by everyone interested in "Hello" eventsinterfaceHelloListener{void someoneSaidHello();}// Someone who says "Hello"classInitiater{privateList<HelloListener> listeners =newArrayList<HelloListener>();publicvoid addListener(HelloListener toAdd){
listeners.add(toAdd);}publicvoid sayHello(){System.out.println("Hello!!");// Notify everybody that may be interested.for(HelloListener hl : listeners)
hl.someoneSaidHello();}}// Someone interested in "Hello" eventsclassResponderimplementsHelloListener{@Overridepublicvoid someoneSaidHello(){System.out.println("Hello there...");}}classTest{publicstaticvoid main(String[] args){Initiater initiater =newInitiater();Responder responder =newResponder();
initiater.addListener(responder);
initiater.sayHello();// Prints "Hello!!!" and "Hello there..."}}
Was passiert, wenn mehrere Threads die Quellereignisse generieren? Wird dies ordnungsgemäß synchronisiert?
Mike G
Kommt auf die Siruation an. Jeder Hörer wird gemäß der von ihm registrierten Reihenfolge benachrichtigt. (Übrigens verstehe ich nicht, was Sie hier mit mehreren Threads meinen. Der Listener-Code wird auf demselben Thread ausgeführt, der das Auftreten des Ereignisses verursacht hat.)
aioobe
8
@GlassGhost: Es wurde abgelehnt, weil es im Grunde ein totales Umschreiben war. Änderungen an der Antwort einer anderen Person sind gut, wenn sie Tippfehler und Formatierungen sowie fehlerhafte Links und dergleichen korrigiert, aber sie sollten den Inhalt nicht radikal ändern. (Einige Ausnahmen gelten für Beiträge mit der Aufschrift "Community-Wiki".)
CHA
1
Hat Java kein eingebautes Ding dafür? Ich würde es wirklich vorziehen, dies in einem abstrakten Muster zu tun und nicht für jedes Ereignis eine for-Schleife zu implementieren.
Tomáš Zato - Wiedereinsetzung Monica
27
Was Sie wollen, ist eine Implementierung des Beobachtermusters . Sie können es komplett selbst machen oder Java-Klassen wie java.util.Observerund verwendenjava.util.Observable
4 Dinge, die beim Werfen von Seitencode benötigt werden:
import java.util.*;//import of java.util.event//Declaration of the event's interface type, OR import of the interface,//OR declared somewhere else in the packageinterfaceThrowListener{publicvoidCatch();}/*_____________________________________________________________*/classThrower{//list of catchers & corresponding function to add/remove them in the listList<ThrowListener> listeners =newArrayList<ThrowListener>();publicvoid addThrowListener(ThrowListener toAdd){ listeners.add(toAdd);}//Set of functions that Throw Events.publicvoidThrow(){for(ThrowListener hl : listeners) hl.Catch();System.out.println("Something thrown");}////Optional: 2 things to send events to a class that is a member of the current class... go to github link to see this code ...}
2 Dinge, die in einer Klassendatei benötigt werden, um Ereignisse von einer Klasse zu empfangen
/*_______________________________________________________________*/classCatcherimplementsThrowListener{//implement added to class//Set of @Override functions that Catch Events@OverridepublicvoidCatch(){System.out.println("I caught something!!");}////Optional: 2 things to receive events from a class that is a member of the current class... go to github link to see this code ...}
@GlassGhost: Das Problem ist, dass maines statisch ist und es keine thisstatische Funktion gibt. Sie müssen new Catcher1()irgendwo eine erstellen und stattdessen diese Instanz übergeben. 1.5 erlaubte auch thisin einem statischen Kontext nicht; Ich bin mir ziemlich sicher, dass es nie erlaubt wurde.
CHao
6
@GlassGhost: Der verwendete Code thisbefindet sich in einem Konstruktor, nicht in main. Deshalb funktioniert es. Bewegen Sie es zu main, und ich garantiere, dass es nicht wird. Das ist es, was die Leute versucht haben, Ihnen zu sagen, und was Ihre Antwort versucht, zu tun. Es ist mir egal, was auf Github läuft - es ist mir egal, was auf SO läuft. Und was Sie auf SO haben, ist kaputt.
CHao
7
@GlassGhost: Ich denke nicht, dass Ihre Antwort insgesamt unzureichend ist. Das Problem , das ich mit ihm zu sehen ist , dass der Code nicht Arbeit wie - Sie versuchen , zu verwenden , thisaus main, die nicht in irgendeiner freigegebenen Version von Java kompilieren. Wenn sich dieser Teil stattdessen in einem Konstruktor befindet oder wenn ein mainerstellt new Catcher1()und stattdessen verwendet wird this, sollte er auch in Version 1.6+ funktionieren.
CHao
6
@GlassGhost: "Eine deklarierte Methode staticwird als Klassenmethode bezeichnet. Eine Klassenmethode wird immer ohne Verweis auf ein bestimmtes Objekt aufgerufen. Es wird versucht, das aktuelle Objekt mit dem Schlüsselwort thisoder dem Schlüsselwort superzu referenzieren oder auf die Typparameter einer Umgebung zu verweisen Die Deklaration im Hauptteil einer Klassenmethode führt zu einem Fehler bei der Kompilierung. " - JLS für Java 5, §8.4.3.2
cHao
31
Dies ist einer der seltsamsten Codestile, die ich je gesehen habe
Eric
4
Das Folgende ist nicht genau dasselbe, aber ähnlich. Ich habe nach einem Snippet gesucht, um einen Aufruf zur Schnittstellenmethode hinzuzufügen, aber diese Frage gefunden. Deshalb habe ich beschlossen, dieses Snippet für diejenigen hinzuzufügen, die wie ich danach gesucht haben und diese Frage gefunden haben ::
Antworten:
Sie möchten wahrscheinlich das Beobachtermuster untersuchen .
Hier ist ein Beispielcode, mit dem Sie beginnen können:
In Verbindung stehender Artikel: Java: Erstellen eines benutzerdefinierten Ereignisses
quelle
Was Sie wollen, ist eine Implementierung des Beobachtermusters . Sie können es komplett selbst machen oder Java-Klassen wie
java.util.Observer
und verwendenjava.util.Observable
quelle
Es gibt drei verschiedene Möglichkeiten, wie Sie dies einrichten möchten:
Thrower
InnenCatcher
Catcher
InnenThrower
Thrower
undCatcher
innerhalb einer anderen Klasse in diesem BeispielTest
DAS ARBEITSGITHUB-BEISPIEL, DAS ICH ZITIERE Standardmäßig wird Option 3 verwendet, um die anderen zu testen , einfach das Kommentar "
Optional
Codeblock der Klasse aus, die Sie als Hauptklasse verwenden möchten, und legen Sie diese Klasse als${Main-Class}
Variable in derbuild.xml
Datei fest:4 Dinge, die beim Werfen von Seitencode benötigt werden:
2 Dinge, die in einer Klassendatei benötigt werden, um Ereignisse von einer Klasse zu empfangen
quelle
main
es statisch ist und es keinethis
statische Funktion gibt. Sie müssennew Catcher1()
irgendwo eine erstellen und stattdessen diese Instanz übergeben. 1.5 erlaubte auchthis
in einem statischen Kontext nicht; Ich bin mir ziemlich sicher, dass es nie erlaubt wurde.this
befindet sich in einem Konstruktor, nicht inmain
. Deshalb funktioniert es. Bewegen Sie es zumain
, und ich garantiere, dass es nicht wird. Das ist es, was die Leute versucht haben, Ihnen zu sagen, und was Ihre Antwort versucht, zu tun. Es ist mir egal, was auf Github läuft - es ist mir egal, was auf SO läuft. Und was Sie auf SO haben, ist kaputt.this
ausmain
, die nicht in irgendeiner freigegebenen Version von Java kompilieren. Wenn sich dieser Teil stattdessen in einem Konstruktor befindet oder wenn einmain
erstelltnew Catcher1()
und stattdessen verwendet wirdthis
, sollte er auch in Version 1.6+ funktionieren.static
wird als Klassenmethode bezeichnet. Eine Klassenmethode wird immer ohne Verweis auf ein bestimmtes Objekt aufgerufen. Es wird versucht, das aktuelle Objekt mit dem Schlüsselwortthis
oder dem Schlüsselwortsuper
zu referenzieren oder auf die Typparameter einer Umgebung zu verweisen Die Deklaration im Hauptteil einer Klassenmethode führt zu einem Fehler bei der Kompilierung. " - JLS für Java 5, §8.4.3.2Das Folgende ist nicht genau dasselbe, aber ähnlich. Ich habe nach einem Snippet gesucht, um einen Aufruf zur Schnittstellenmethode hinzuzufügen, aber diese Frage gefunden. Deshalb habe ich beschlossen, dieses Snippet für diejenigen hinzuzufügen, die wie ich danach gesucht haben und diese Frage gefunden haben ::
Die Verwendung ist wie folgt:
quelle