局部变量必须是最终的或有效的最终

use*_*127 1 java java-8

我在Java 8中有一个异步操作,它返回一个onError回调或onSuccess回调.如果操作成功与否,我需要返回我的方法内部.所以我返回一个布尔值来说明这个信息.我遇到的问题是我得到以下编译错误:

错误:从内部类引用的局部变量必须是最终的或有效的最终

谷歌搜索错误我可以看到你不允许这种类型的操作,但如果操作成功与否,我怎么能返回?

 public Boolean addUser(String email, String password) {

    Boolean isSuccess = false;

    Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
    item.put("email", new AttributeValue(email)); //email
    item.put("password", new AttributeValue(password)); //password

    dynamoDB.putItemAsync(new PutItemRequest().withTableName("Users").withItem(item), new AsyncHandler() {
        @Override
        public void onError(Exception excptn) {

        }

        @Override
        public void onSuccess(AmazonWebServiceRequest rqst, Object result) {
            isSuccess = true;
        }

    });

        return isSuccess;

}
Run Code Online (Sandbox Code Playgroud)

Hoo*_*pje 8

首先,我将解释错误信息的含义,然后我将告诉您设计有什么问题,并建议做什么.

一,错误信息.isSuccess是一个局部变量,也就是说,一旦方法addUser完成,它就消失了.但是,AsyncHandler您创建的实例可能会比这更长.如果是,它将引用一个不再存在的变量.

如果变量是最终的或有效的最终变量,这不会成为问题.然后我们就知道变量永远不会改变,所以我们可以将变量复制到新创建的对象并引用该副本.请注意,在引用变量的情况下,它是不会更改的引用,它引用的对象可能仍会被修改.

为了避免这个问题,Java的创建者已经决定从匿名内部类(或lambda表达式)中不能引用非最终(或有效最终)的局部变量.错误消息告诉您正是这样做的.

所以现在你的设计.您的设计无法以这种方式工作.该AsyncHandler实例可能会活到方法完成之后.它的方法可能在不同的线程中执行,因此很可能在addUser方法完成后调用它的方法.那应该addUser回归什么?在它完成的那一刻,它甚至可能不知道操作是否成功!

您可以异步执行操作,即在不同的线程上执行操作.此操作可能需要1毫秒,或1分钟,甚至10年.如果要查看该操作是否成功,则必须以某种方式将其结果传递给执行的线程addUser.

线程间通信不是一项简单的任务,但你很幸运:putItemAsync返回一个Future实例,Future该类的目的正是你想要做的:找出异步操作是否已经完成并获得其结果.

要检查异步操作是否已完成,请轮询isDone()返回的方法Future.如果完成,您可以通过调用get()方法获得操作的结果Future.如果操作被异常中止,因为它抛出一个异常,get()将引发ExecutionExceptiongetCause()是抛出的异常.

或者,当然,您决定使用该putItem方法同步(在同一个线程上)运行操作.然后你的方法将等待操作完成,你立即得到结果.