如何在类之间执行 JAVA 回调?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18279302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I perform a JAVA callback between classes?
提问by ágota Horváth
I am coming from JavaScript, in which callbacks are pretty easy. I am trying to implement them into JAVA, without success.
我来自 JavaScript,其中回调非常简单。我正在尝试将它们实现到 JAVA 中,但没有成功。
I have a Parent class:
我有一个父类:
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
ExecutorService workers = Executors.newFixedThreadPool(10);
private ServerConnections serverConnectionHandler;
public Server(int _address) {
System.out.println("Starting Server...");
serverConnectionHandler = new ServerConnections(_address);
serverConnectionHandler.newConnection = function(Socket _socket) {
System.out.println("A function of my child class was called.");
};
workers.execute(serverConnectionHandler);
System.out.println("Do something else...");
}
}
Then I have a child class, that is called from the parent:
然后我有一个子类,从父类调用:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerConnections implements Runnable {
private int serverPort;
private ServerSocket mainSocket;
public ServerConnections(int _serverPort) {
serverPort = _serverPort;
}
@Override
public void run() {
System.out.println("Starting Server Thread...");
try {
mainSocket = new ServerSocket(serverPort);
while (true) {
newConnection(mainSocket.accept());
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void newConnection(Socket _socket) {
}
}
What is the right way of implementing the
什么是实施的正确方法
serverConnectionHandler.newConnection = function(Socket _socket) {
System.out.println("A function of my child class was called.");
};
part, in the Parent class, which is clearly not correct?
部分,在 Parent 类中,这显然是不正确的?
采纳答案by Diego C Nascimento
Define an interface, and implement it in the class that will receive the callback.
定义一个接口,并在接收回调的类中实现它。
Have attention to the multi-threading in your case.
请注意您的情况下的多线程。
Code example from http://cleancodedevelopment-qualityseal.blogspot.com.br/2012/10/understanding-callbacks-with-java.html
来自http://cleancodedevelopment-qualityseal.blogspot.com.br/2012/10/understanding-callbacks-with-java.html 的代码示例
interface CallBack { //declare an interface with the callback methods, so you can use on more than one class and just refer to the interface
void methodToCallBack();
}
class CallBackImpl implements CallBack { //class that implements the method to callback defined in the interface
public void methodToCallBack() {
System.out.println("I've been called back");
}
}
class Caller {
public void register(CallBack callback) {
callback.methodToCallBack();
}
public static void main(String[] args) {
Caller caller = new Caller();
CallBack callBack = new CallBackImpl(); //because of the interface, the type is Callback even thought the new instance is the CallBackImpl class. This alows to pass different types of classes that have the implementation of CallBack interface
caller.register(callBack);
}
}
In your case, apart from multi-threading you could do like this:
在您的情况下,除了多线程之外,您还可以这样做:
interface ServerInterface {
void newSeverConnection(Socket socket);
}
public class Server implements ServerInterface {
public Server(int _address) {
System.out.println("Starting Server...");
serverConnectionHandler = new ServerConnections(_address, this);
workers.execute(serverConnectionHandler);
System.out.println("Do something else...");
}
void newServerConnection(Socket socket) {
System.out.println("A function of my child class was called.");
}
}
public class ServerConnections implements Runnable {
private ServerInterface serverInterface;
public ServerConnections(int _serverPort, ServerInterface _serverInterface) {
serverPort = _serverPort;
serverInterface = _serverInterface;
}
@Override
public void run() {
System.out.println("Starting Server Thread...");
if (serverInterface == null) {
System.out.println("Server Thread error: callback null");
}
try {
mainSocket = new ServerSocket(serverPort);
while (true) {
serverInterface.newServerConnection(mainSocket.accept());
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Multi-threading
多线程
Remember this does not handle multi-threading, this is another topic and can have various solutions depending on the project.
请记住,这不处理多线程,这是另一个主题,可以根据项目有各种解决方案。
The observer-pattern
观察者模式
The observer-pattern does nearly this, the major difference is the use of an ArrayList
for adding more than one listener. Where this is not needed, you get better performance with one reference.
观察者模式几乎做到了这一点,主要区别在于使用 anArrayList
来添加多个侦听器。在不需要的地方,您可以通过一个参考获得更好的性能。
回答by sanbhat
IMO, you should have a look at the Observer Pattern, and this is how most of the listeners work
IMO,你应该看看Observer Pattern,这就是大多数监听器的工作方式
回答by William Morrison
Use the observer pattern. It works like this:
使用观察者模式。它是这样工作的:
interface MyListener{
void somethingHappened();
}
public class MyForm implements MyListener{
MyClass myClass;
public MyForm(){
this.myClass = new MyClass();
myClass.addListener(this);
}
public void somethingHappened(){
System.out.println("Called me!");
}
}
public class MyClass{
private List<MyListener> listeners = new ArrayList<MyListener>();
public void addListener(MyListener listener) {
listeners.add(listener);
}
void notifySomethingHappened(){
for(MyListener listener : listeners){
listener.somethingHappened();
}
}
}
You create an interface which has one or more methods to be called when some event happens. Then, any class which needs to be notified when events occur implements this interface.
您创建一个接口,该接口具有一个或多个在发生某些事件时要调用的方法。然后,任何需要在事件发生时通知的类都实现了这个接口。
This allows more flexibility, as the producer is only aware of the listener interface, nota particular implementation of the listener interface.
这提供了更大的灵活性,因为生产者只知道侦听器接口,而不知道侦听器接口的特定实现。
In my example:
在我的例子中:
MyClass
is the producer here as its notifying a list of listeners.
MyClass
是这里的生产者,因为它通知了一个听众列表。
MyListener
is the interface.
MyListener
是界面。
MyForm
is interested in when somethingHappened
, so it is implementing MyListener
and registering itself with MyClass
. Now MyClass
can inform MyForm
about events without directly referencing MyForm
. This is the strength of the observer pattern, it reduces dependency and increases reusability.
MyForm
对 when 感兴趣somethingHappened
,所以它正在实现MyListener
和注册自己MyClass
。现在MyClass
可以MyForm
在不直接引用的情况下通知事件MyForm
。这是观察者模式的优势,它减少了依赖性并增加了可重用性。
回答by pichsenmeister
I don't know if this is what you are looking for, but you can achieve this by passing a callback to the child class.
我不知道这是否是您要找的,但是您可以通过将回调传递给子类来实现这一点。
first define a generic callback:
首先定义一个通用回调:
public interface ITypedCallback<T> {
void execute(T type);
}
create a new ITypedCallback instance on ServerConnections instantiation:
在 ServerConnections 实例化上创建一个新的 ITypedCallback 实例:
public Server(int _address) {
serverConnectionHandler = new ServerConnections(new ITypedCallback<Socket>() {
@Override
public void execute(Socket socket) {
// do something with your socket here
}
});
}
call the execute methode on the callback object.
在回调对象上调用执行方法。
public class ServerConnections implements Runnable {
private ITypedCallback<Socket> callback;
public ServerConnections(ITypedCallback<Socket> _callback) {
callback = _callback;
}
@Override
public void run() {
try {
mainSocket = new ServerSocket(serverPort);
while (true) {
callback.execute(mainSocket.accept());
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
btw: I didn't check if it's 100% correct, directly coded it here.
btw:我没有检查它是否 100% 正确,直接在这里编码。
回答by akkerman
In this particular case, the following should work:
在这种特殊情况下,以下应该起作用:
serverConnectionHandler = new ServerConnections(_address) {
public void newConnection(Socket _socket) {
System.out.println("A function of my child class was called.");
}
};
It's an anonymous subclass.
它是一个匿名子类。