Java 局部变量必须是最终变量或有效的最终变量
我在Java8中有一个异步操作,它返回onError回调或onSuccess回调。如果手术成功与否,我需要返回我的方法内部。所以我返回一个布尔值来表示这个信息。我面临的问题是出现以下编译错误: 错误:从内部类引用的局部变量必须是final或final 有效最终 谷歌搜索错误我可以看到你这种类型的操作是不允许的,但是如果操作成功与否,我如何返回Java 局部变量必须是最终变量或有效的最终变量,java,java-8,Java,Java 8,我在Java8中有一个异步操作,它返回onError回调或onSuccess回调。如果手术成功与否,我需要返回我的方法内部。所以我返回一个布尔值来表示这个信息。我面临的问题是出现以下编译错误: 错误:从内部类引用的局部变量必须是final或final 有效最终 谷歌搜索错误我可以看到你这种类型的操作是不允许的,但是如果操作成功与否,我如何返回 public Boolean addUser(String email, String password) { Boolean isSucce
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
实例的寿命可能会更长。如果是,它将引用一个不再存在的变量
如果变量是最终变量或实际上是最终变量,则这不会是一个问题。这样我们就知道变量永远不会改变,所以我们可以将变量复制到新创建的