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

Java 局部变量必须是最终变量或有效的最终变量,java,java-8,Java,Java 8,我在Java8中有一个异步操作,它返回onError回调或onSuccess回调。如果手术成功与否,我需要返回我的方法内部。所以我返回一个布尔值来表示这个信息。我面临的问题是出现以下编译错误: 错误:从内部类引用的局部变量必须是final或final 有效最终 谷歌搜索错误我可以看到你这种类型的操作是不允许的,但是如果操作成功与否,我如何返回 public Boolean addUser(String email, String password) { Boolean isSucce

我在Java8中有一个异步操作,它返回onError回调或onSuccess回调。如果手术成功与否,我需要返回我的方法内部。所以我返回一个布尔值来表示这个信息。我面临的问题是出现以下编译错误:

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

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

 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;

}
public Boolean addUser(字符串电子邮件、字符串密码){
布尔值isSuccess=false;
Map item=newhashmap();
item.put(“email”,新属性值(email));//email
item.put(“密码”,新属性值(密码));//密码
dynamoDB.putItemAsync(新的PutItemRequest().withTableName(“用户”)。withItem(item),新的AsyncHandler(){
@凌驾
公共无效单错误(例外情况除外){
}
@凌驾
成功时公共无效(AmazonWebServiceRequest rqst,对象结果){
isSuccess=true;
}
});
返回成功;
}

这不是一个好的做法,而且可能不起作用。在代码中,
new asynchHandler()
将在单独的线程中运行。因为它不是阻塞调用,所以主线程不会等待它的完成

因此,在调用
dynamoDB.putItemAsync(…)
之后,甚至在
AsyncHandler()
完成执行并更改
isSuccess
的值之前,返回语句就会被执行。这意味着,
返回issucess
可能返回默认值
false

注意:如果您真的想这样做,可以将布尔变量设置为字段变量

public boolean isSuccess = false;

这不是一个好的做法,也可能不起作用。在代码中,
new asynchHandler()
将在单独的线程中运行。因为它不是阻塞调用,所以主线程不会等待它的完成

因此,在调用
dynamoDB.putItemAsync(…)
之后,甚至在
AsyncHandler()
完成执行并更改
isSuccess
的值之前,返回语句就会被执行。这意味着,
返回issucess
可能返回默认值
false

注意:如果您真的想这样做,可以将布尔变量设置为字段变量

public boolean isSuccess = false;

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

首先是错误消息
isSuccess
是一个局部变量,也就是说,只要方法
addUser
完成,它就消失了。但是,您创建的
asynchHandler
实例的寿命可能会更长。如果是,它将引用一个不再存在的变量

如果变量是最终变量或实际上是最终变量,则这不会是一个问题。然后我们知道变量永远不会改变,所以我们可以将变量复制到新创建的对象并引用该副本。注意,在引用变量的情况下,引用不会改变,它引用的对象可能仍然会被修改

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

现在来看看你的设计。您的设计不能以这种方式工作。
asynchHandler
实例可能会一直存在到方法完成之后。它的方法可能会在不同的线程中执行,因此它的方法很可能在
addUser
方法完成后被调用。那么
addUser
应该返回什么呢?在它完成的那一刻,它甚至可能不知道操作是否成功

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

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

要检查异步操作是否已完成,请轮询返回的
Future
isDone()
方法。如果完成,您可以通过调用
Future
get()
方法来获得操作的结果。如果操作因引发异常而异常中止,
get()
将引发一个
ExecutionException
,其
getCause()
是引发的异常


当然,您也可以决定使用
putItem
方法同步运行操作(在同一线程上)。然后,您的方法将等待操作完成,您将立即得到结果。

首先,我将解释错误消息的含义,然后我将告诉您您的设计有什么问题,并建议如何处理

首先是错误消息
isSuccess
是一个局部变量,也就是说,只要方法
addUser
完成,它就消失了。但是,您创建的
asynchHandler
实例的寿命可能会更长。如果是,它将引用一个不再存在的变量

如果变量是最终变量或实际上是最终变量,则这不会是一个问题。这样我们就知道变量永远不会改变,所以我们可以将变量复制到新创建的