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..."}}
¿Hay alguna razón legítima por la cual stackoverflow.com/suggested-edits/237242 no se realizó? Muestra cómo hacer esto con 2 clases como se hizo originalmente en la pregunta.
GlassGhost
2
¿Qué sucede si múltiples hilos generan los eventos fuente? ¿Se sincronizará esto correctamente?
Mike G
Depende de la sirutación. Cada oyente será notificado de acuerdo con el orden en que se registraron. (Por cierto, no entiendo lo que quieres decir con múltiples hilos aquí. El código del oyente se ejecutará en el mismo hilo que causó el evento.)
aioobe
8
@GlassGhost: fue rechazado porque era básicamente una reescritura total. Las ediciones a la respuesta de otra persona son buenas si arreglan errores tipográficos y formateo y enlaces rotos, pero no deberían cambiar radicalmente el contenido. (Se aplican algunas excepciones para las publicaciones marcadas como "wiki de la comunidad")
CHao
1
¿Java no tiene nada incorporado para esto? Realmente preferiría hacer esto en un patrón abstracto, no implementar bucle para cada evento.
Tomáš Zato - Restablece a Mónica el
27
Lo que quieres es una implementación del patrón de observador . Puede hacerlo usted mismo por completo, o usar clases de Java como java.util.Observeryjava.util.Observable
Hay 3 formas diferentes en que puede configurar esto:
Thrower dentro de Catcher
Catcher dentro de Thrower
Throwery Catcherdentro de otra clase en este ejemploTest
EL EJEMPLO DE GITHUB DE TRABAJO QUE ESTOY CITANDO Por defecto a la Opción 3, para probar los otros simplemente descomente el "Optional" bloque de código de la clase que desea que sea principal y configure esa clase como la${Main-Class}variable en elbuild.xmlarchivo:
4 cosas necesarias para lanzar el código lateral:
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 cosas necesarias en un archivo de clase para recibir eventos de una clase
/*_______________________________________________________________*/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: El problema es que maines estático y no existe thisen una función estática. Necesita crear un new Catcher1()lugar y pasar esa instancia en su lugar. 1.5 tampoco permitió thisen un contexto estático; Estoy bastante seguro de que nunca se ha permitido.
cHao
66
@GlassGhost: el código que usa thisestá en un constructor, no en main. Por eso funciona. Muévelo a main, y te garantizo que no. Eso es lo que la gente ha estado tratando de decirte, y lo que tu respuesta está tratando de hacer. Me importa un bledo lo que hay en Github, me importa lo que hay en SO. Y lo que tienes en SO está roto.
cHao
77
@GlassGhost: No creo que su respuesta sea inadecuada en general. El problema que veo con esto es que el código no funcionará como es - usted está tratando de utilizar thisa partir main, que no se compilará en cualquier versión de lanzamiento de Java. Si esa parte estuviese en un constructor, o si hubiera maincreado new Catcher1()y usado eso en lugar de this, debería funcionar, incluso en 1.6+.
cHao
66
@GlassGhost: "Un método que se declara staticse llama método de clase. Un método de clase siempre se invoca sin referencia a un objeto en particular. Un intento de hacer referencia al objeto actual usando la palabra clave thiso la palabra clave supero para hacer referencia a los parámetros de tipo de cualquier entorno declaración en el cuerpo de un método de clase da como resultado un error en tiempo de compilación ". - JLS para Java 5, §8.4.3.2
cHao
31
Este es uno de los estilos de código más extraños que he visto
Eric
4
Lo siguiente no es exactamente lo mismo pero similar, estaba buscando un fragmento para agregar una llamada al método de interfaz, pero encontré esta pregunta, así que decidí agregar este fragmento para aquellos que lo estaban buscando como yo y encontré esta pregunta :
Respuestas:
Probablemente quieras mirar en el patrón de observador .
Aquí hay un código de muestra para comenzar:
Artículo relacionado: Java: crear un evento personalizado
fuente
Lo que quieres es una implementación del patrón de observador . Puede hacerlo usted mismo por completo, o usar clases de Java como
java.util.Observer
yjava.util.Observable
fuente
Hay 3 formas diferentes en que puede configurar esto:
Thrower
dentro deCatcher
Catcher
dentro deThrower
Thrower
yCatcher
dentro de otra clase en este ejemploTest
EL EJEMPLO DE GITHUB DE TRABAJO QUE ESTOY CITANDO Por defecto a la Opción 3, para probar los otros simplemente descomente el "
Optional
" bloque de código de la clase que desea que sea principal y configure esa clase como la${Main-Class}
variable en elbuild.xml
archivo:4 cosas necesarias para lanzar el código lateral:
2 cosas necesarias en un archivo de clase para recibir eventos de una clase
fuente
main
es estático y no existethis
en una función estática. Necesita crear unnew Catcher1()
lugar y pasar esa instancia en su lugar. 1.5 tampoco permitióthis
en un contexto estático; Estoy bastante seguro de que nunca se ha permitido.this
está en un constructor, no enmain
. Por eso funciona. Muévelo amain
, y te garantizo que no. Eso es lo que la gente ha estado tratando de decirte, y lo que tu respuesta está tratando de hacer. Me importa un bledo lo que hay en Github, me importa lo que hay en SO. Y lo que tienes en SO está roto.this
a partirmain
, que no se compilará en cualquier versión de lanzamiento de Java. Si esa parte estuviese en un constructor, o si hubieramain
creadonew Catcher1()
y usado eso en lugar dethis
, debería funcionar, incluso en 1.6+.static
se llama método de clase. Un método de clase siempre se invoca sin referencia a un objeto en particular. Un intento de hacer referencia al objeto actual usando la palabra clavethis
o la palabra clavesuper
o para hacer referencia a los parámetros de tipo de cualquier entorno declaración en el cuerpo de un método de clase da como resultado un error en tiempo de compilación ". - JLS para Java 5, §8.4.3.2Lo siguiente no es exactamente lo mismo pero similar, estaba buscando un fragmento para agregar una llamada al método de interfaz, pero encontré esta pregunta, así que decidí agregar este fragmento para aquellos que lo estaban buscando como yo y encontré esta pregunta :
El uso es el siguiente:
fuente