1

I have Java code that roughly goes like this:

public String render(String str) {
  byte[] b = [serialize str]
  client.sendRequest(b, new Callback<byte[]>() {
    @Override
    public void onDone(byte[] data) {
      String res = [convert data back to String]
      // TODO: return this string in the outer function
  }); 
  return "???"; 
}

I'm having issues getting the render function to return the String that I obtain from the onDone callback. I tried initializing the String res outside of the sendRequest invocation but I run into issues with the variable not being final.

I was also reading up on Java Futures here. From that I was thinking I could set a Future and call isDone() on it to make sure it was set? However this code seems verbose and I was wondering if there was a simpler solution.

cheng
  • 1,264
  • 2
  • 18
  • 41
  • There is no serialization required/relevant here. Whatever problem exists - a scoping/timing issue - will remain removing any mention of such. Ie. try to "return `data`", which won't work for the same conceptual reason. One asynchronous code is used, the model *must* be switched to an asynchronous model entirely (including Futures, which just defer the decision, or further processing in callbacks) or use a synchronous method (which can including 'synchronously waiting for an asynchronous method to complete'). – user2864740 Jun 25 '16 at 01:30

1 Answers1

2

I'm having issues getting the render function to return the String that I obtain from the onDone callback. I tried initializing the String res outside of the sendRequest invocation but I run into issues with the variable not being final.

You can't change final variable of primitive or immutable type from anonymous class, and can't access non final. So you can:

  • Use named inner class instead of anonymous

  • Use final object of mutable class (StringBuilder or StringBuffer)

  • Create mutable class that will be just "holder" of required value, create final variable of its type, and set value to it from anonymous class; or use array of required type for the same purpose.

[see this ]

But before returning value from outer function you obviously should wait until method in anonymous class will finish its work.

Community
  • 1
  • 1
B-GangsteR
  • 2,534
  • 22
  • 34
  • Thanks, I looked at the link and tried using the solution by making a final String[] and setting index 0 but someone told me that in Java, if I'm running on separate threads, that 0th index is not guaranteed to be set. I ended up using an ArrayBlockingQueue to achieve synchronous behavior for this one. – cheng Jun 27 '16 at 19:05