Search code examples
javagwtscjp

Retrieve the result of a method that is received in an anonymous innerclass callback?


I have a little question here.

private boolean isSomethingTrue(String param) {
    boolean result = false;
    myService.hasAlerts(param,new Callback<Boolean>(
        @Override
        public void onSuccess(Boolean hasAlerts) {
            result = hasAlerts;
        }
    });
    return result;
}

On this code, how can i return the boolean hasAlerts that is received in the callback? This doesn't work because the result variable is not final. But when it's final, it can't be modified so...

I've done something like that:

private boolean isSomethingTrue(String param) {
    class ResultHolder {
        boolean result=false;
    }
    final ResultHolder resultHolder = new ResultHolder();
    myService.findBoolean(param,new Callback<Boolean>(
        @Override
        public void onSuccess(Boolean hasAlerts) {
            resultHolder.result = hasAlerts;
        }
    });
    return resultHolder.result;
}

But is there a simpler solution to handle such a case?

I've found this problem while trying to call a GWT RPC service.


Solution

  • I can think of a few variations--none of them particularly exciting. You could merge the result holder and callback into a single class and make it static if you could use it elsewhere, but it's not really an improvement.

    private boolean isSomethingTrue(String param) {
        class MyCallback implements Callback<Boolean> {
            boolean result = false;
            @Override
            public void onSuccess(Boolean hasAlerts) {
                result = hasAlerts;
            }
        }
        final MyCallback callback = new MyCallback();
        myService.findBoolean(param, callback);
        return callback.result;
    }
    

    You could implement a generic synchronous Future, but that might be misleading.

    Finally, if you're doing this often you could genericize the value holder.

    public class Result<T> {
        private T value;
        public void set(T value) { this.value = value; }
        public T get() { return value; }
    }
    
    private boolean isSomethingTrue(String param) {
        final Result<Boolean> result = new Result<Boolean>();
        myService.findBoolean(param,new Callback<Boolean>(
            @Override
            public void onSuccess(Boolean hasAlerts) {
                result.set(hasAlerts);
            }
        });
        return result.get();
    }