First I will explain what the error message means, then I will tell you what is wrong with your design and suggest what to do.
First, the error message. isSuccess
is a local variable, that is, as soon as the method addUser
finishes, it is gone. However, the AsyncHandler
instance you create might live longer than that. If it does, it would refer to a variable which doesn't exist anymore.
This would not be a problem if the variable were final or effectively final. Then we would know that the variable will never change, so we could just copy the variable to the newly created object and refer to that copy. Note that in case of a reference variable, it is the reference that doesn't change, the object it refers to might still be modified.
To circumvent this problem, the creators of Java have decided that from an anonymous inner class (or a lambda expression) you cannot refer to a local variable that is not final (or effectively final). The error message tells you that you're doing exactly that.
So now to your design. Your design cannot work in this way. The AsyncHandler
instance will probably live until after the method finishes. Its methods will be probably executed in a different thread, so it's likely that its methods are called after your addUser
method finishes. So what should addUser
return? At the moment that it finishes, it might not even know whether the operation was successful not!
You perform an operation asynchronously, that is, on a different thread. This operation might take 1 millisecond, or 1 minute, or even 10 years. If you want to see if that operation was successful, you must somehow communicate its result to the thread that executes addUser
.
Inter-thread communication is not a trivial task, but you're lucky: the putItemAsync
returns a Future
instance, and the Future
class is intended for exactly what you want to do: find out if an asynchronous operation has finished and obtain its result.
To check whether the asynchronous operation has finished, poll the isDone()
method of the returned Future
. If it finished, you can obtain the result of the operation by calling the get()
method of the Future
. If the operation was aborted abnormally because it threw an exception, get()
will throw an ExecutionException
whose getCause()
is the thrown exception.
Or, of course, you decide to run the operation synchronously (on the same thread) using the putItem
method. Then your method will wait for the operation to finish and you have the result immediately.