首页 > 解决方案 > 在封闭范围内定义的 Bool var dbgotAltered

问题描述

我对 Java 很陌生,但我也很确定我在这里尝试做的事情不会干扰任何未来或过去的时间线,但 Eclipse 肯定不会让我超越这一点。我真的不明白为什么会发生这种情况或如何解决这个问题?

简单地说:我正在调用一个可以删除记录的函数/方法(如果按下按钮)。调用方法只是想知道用户是否删除(更改)了数据库?我用过这样的布尔值没有任何问题。我看过 lambda、final 等,但我的专业知识还不够,但同样,这是一项非常简单的任务。谢谢!

static Boolean EditRecord(int listboxIndex) {

Boolean dbgotAltered = false;
.
.
JButton button1 = new JButton("Delete"); 
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {     

dbData.remove(listboxIndex);
dbgotAltered = true;

//  Local variable dbgotAltered defined in an 
//  enclosing scope must be final or effectively final
//  Looking for a fix for dbgotAltered. The Calling
//  procedure/method really wants to know?              
}
});     
.
.
return dbgotAltered;
}

标签: javascopeboolean

解决方案


错误没有说谎。内部类或 lambda 作用域中使用的任何变量都必须是“标记”为最终变量,或者必须是“有效”最终变量(意思是,您可以将其标记为最终变量)。

原因显示在您的代码段中。

您的代码段无法在此处执行您想要的操作。

代码就像烘焙的食谱:

  1. 混合面粉和鸡蛋。
  2. 揉好。
  3. 卷成意大利面。

你在这里做的是一个小把戏:

  1. 混合面粉和鸡蛋。
  2. 发邮件给你的朋友来你家好好揉捏。
  3. 不要等待,继续前进,将生鸡蛋和未揉搓的面粉直接卷成意大利面。你的厨房现在一团糟。
  4. 几个小时后,你的朋友看到​​你的邮件,出现了,然后就走了??????这里发生了什么?

您正在配置的那个动作监听器?里面的代码不会立即运行。当用户按下您的按钮时,它将运行。从现在起很容易 5 小时后,你不知道。该行addActionListener所做的只是将侦听器与按钮相关联。它不会等待用户实际操作它的拇指——该调用立即返回。它只是告诉按钮当用户按下按钮时该做什么。

因此,这段代码运行return dbgotAltered;并且显然总是返回 false - 用户无法在系统执行那行代码的 1 纳秒内按下该按钮。

所以,这里有两个问题:

  1. 您不能在 lambdas/匿名类中读取或写入非有效最终变量(并且此 ActionListener 定义是匿名类)。您可以通过使用级别间接来解决此问题,例如 via AtomicBoolean

  2. ...但你对这里的时间感到困惑。editRecord 方法不能返回用户是否按下按钮,你需要完全不同的代码。最有可能的是,按下按钮的行为应该会导致一些代码运行。


推荐阅读