【问题标题】:Anonymous Listener inside for loopfor循环中的匿名侦听器
【发布时间】:2015-05-14 13:46:25
【问题描述】:

这可能是一个愚蠢的问题,但在我的代码中,当在面板上执行 mouseClicked 时,循环条件中的 item 是否与 item 的 item 参数相同strong>ItemDialog?

for (Item item: itemsList) {
        JPanel panel = new ItemPanel(item);
        panel.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent arg0) {
                new ItemDialog(item);
            }
            public void mouseEntered(MouseEvent arg0) {}
            public void mouseExited(MouseEvent arg0) {}
            public void mousePressed(MouseEvent arg0) {}
            public void mouseReleased(MouseEvent arg0) {}
});

【问题讨论】:

  • 是的。您的for-each 循环中没有其他item,因此参考很简单。在你的IDE中调试代码,你看到了什么?
  • 致反对者:这不是一个愚蠢的问题。这是一个关于匿名内部类令人困惑的范围界定的好问题,以及它们如何保证未来的价值仍然相同。加上循环范围的变量。加上 Java-8 自动生成变量final
  • 我不明白反对意见。有几十个问题是错误的假设导致了错误,例如stackoverflow.com/questions/8327781/(编辑:或简称:我同意勺子先生)
  • 也许用java版本标记它,如果这个字段中的7和8之间有区别?我会说它首先不会编译。感谢@MrSpoon 指出我不知道的差异。

标签: java mouselistener


【解决方案1】:

是的,答案很简单。

但是,正如我在评论中所说,这里发生了很多事情!

匿名内部类令人困惑:类似于 Javascript 中的闭包。

他们可以访问在他们之外定义的变量。他们可以仍然在将来的任意点访问这些相同的变量引用,即使变量超出范围也是如此。使这成为可能的规则是这些变量必须声明为final

这篇文章比我更好地解释了机制:How does java implement inner class closures?

顺便说一句:从 Java 8 开始,编译器自动将您的每个 Item item 变量变为 final,因为它发现它们正在您的匿名内部类中使用。所以他们实际上变成了:

for (final Item item: itemsList) {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2011-03-07
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    相关资源
    最近更新 更多