Java - asynchronous methods with return value

笑着哭i 提交于 2020-01-06 08:10:12

问题


I have a question about asynchronous method calls in java, especially about the response value of the async method.

The situation is the following:

The async method I want to call is..

public void getSpeed(IResponseListener listener) {
....
}

The interface of the listener is...

interface IResponseListener {
    public void response(ResponseEvent event);
}

This method is called when the async method has a response value

My problem now is that the class ResponseEvent has an attribute response that can be of any type (boolean,float,String...)and in the implementation of the interface IResponseListener I have to cast the value...

IResponseListener listener = new IResponseListener {

    public void response(ResponseEvent event) {
        float f = (float)event.response;
    }
}

Is this a good solution to handle this? I think the bad thing is that the response listener HAS to know the type of the response! Is there a better solution to handle asynchronous calls that want to give a response even if the response can be of any type?


回答1:


I would have done as @nico_ekito says...Or use your existing solution. It is a problem that you don't know the result type.

Anyway, you could do some adjustments and let the ResponseEvent class do the casting for you.

ResponseListener.java

interface IResponseListener {
    void response(ResponseEvent event);
}

ResponseEvent.java

public class ResponseEvent {

   private Object response;

   @SuppressWarnings("unchecked")
   public <T> T getResponse() {
       return (T)response;
   }

   public <T> void setResponse(T response) {
       this.response = response;
   }
}

Usage:

IResponseListener listener = new IResponseListener() {
    public void response(ResponseEvent event) {
        float f = event.getResponse();
    } 
};

Please note that you will get a ClassCastException if your type is something other than what you expect it to be.




回答2:


I think a lot of these answers are starting to look like this->

public interface Function<Args, Value>
{
  public Value call(Args args);
}

Your return type doesn't matter--if it can return multiple types, then the "multiple types" are a type...might I suggest a type of JSON considering what you're looking at?

The reality is you can't expect your handler to know the type in advance so you need to specify that. Whether this is with the return type or the class is up to you.

I could easily see doing a class hierarchy:

public class ResponseString implements Function<Args, String>; 
public class ResponseNumber implements Function<Args, Number>;
...
public class ResponseType implements Function<Args, Type>;

or simply creating a type that has all the information you need. The long and short is that the method can DEFINE what it expects for the types and you have the ability to extend them. Keep in mind that response could also be a Function which could be executed. There's nothing wrong with knowing what to DO with something and not knowing what it is ->

Example->

//Admittedly I'd probably have a "Procedure or VoidFunction interface as well".
public yourMethod(Function<String args, Function<String,?> handler)
{
  String hello = "hello";
  Function<String,?> function = handler.call(hello);
  function.call(hello); 
} 

I hope this helps. Sometimes there's no reason to go this far, and sometimes there is. You don't know the type--it seems like maybe you're hoping someone else will provide it and this can do that for you while remaining strict.

EDIT: the example of have for this in one framework is:

  Applcation.openDialog(Dialog dialog, Callable<Boolean> onClose);

This returns true of the dialog cleans up and closes and false if not. I don't really care what happens here, I do care that it tells me yes, close it, or no don't.




回答3:


Use Java generics:

interface IResponseListener<T> {
    public void response(T response);
}

Then, in an anonymous class:

IResponseListener listener = new IResponseListener<Float> {

    public void response(Float response) {
        float f = response;
    }
}



回答4:


I don't know whether this is correct, but if you are going to handle the return value differently, why not overload the response method with different type of objects that you would expect. Just a suggestion..

interface InterfaceName{
    void response(float responseVal);
    void response(boolean responseVal);
    ...
}


来源:https://stackoverflow.com/questions/12680273/java-asynchronous-methods-with-return-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!