在Java 8中使用lambdas时出现意外错误
我使用的是
Java 8 Update 20 32位,Maven 3.2.3,Eclipse Luna Build id:20140612-0600 32位.
在开始使用lambdas之后,我的项目中的一些类开始报告maven中的编译错误(mvn compile). 只有在我使用lambdas时才会出现这些错误.如果我切换回匿名类,错误就消失了. 我可以通过一个简单的测试用例重现错误: package br; import java.awt.Button; import java.awt.Panel; public class Test { private final Button button; private final Panel panel; public Test() { button = new Button(); button.addActionListener(event -> { System.out.println(panel); }); panel = new Panel(); } } 我这样编译: mvn clean;mvn compile 我收到这个错误: [ERROR] /C:/Users/fabiano/workspace-luna/Test/src/main/java/br/Test.java:[14,44] variable panel might not have been initialized 虽然错误信息非常清楚正在发生的事情(编译器认为最终变量面板在实例化之前被调用),但是在按钮生成动作之前不会调用变量,以及我们怎么也不能说动作将发生,代码应该编译.实际上,如果我不使用lambda,它会按照它应该编译: package br; import java.awt.Button; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Test { private final Button button; private final Panel panel; public Test() { button = new Button(); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(panel); } }); panel = new Panel(); } } 我注意到与此问题相关的其他两个奇怪的事情: > Eclipse在自动编译类时不会报告此错误. Eclipse使用与maven相同的JDK来编译类. 有人可以帮我解决这个问题吗?或者尝试重现这个问题? 解决方法
您应该考虑编译器遵循正式规则并且不了解您的事实.特别是,编译器无法知道方法addActionListener不会立即调用actionPerformed方法.它也不知道按钮的可见性,它确定何时可以调用actionPerformed. 正式行为has a specification.在那里你会发现以下几点: Chapter 16. Definite Assignment
和 15.27.2. Lambda Body
在你的代码中,lambda体内名称的含义,面板读取,与构造函数周围的上下文相同.在该上下文中,适用“当其值发生任何访问时,每个空白最终字段必须具有明确赋值的”规则. 而且,是的,这与内部类定义不同.规范明确指出了这一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Spring boot工具类静态属性注入及多环境配置详解
- java – 依赖于同一Gradle依赖项目的main和test代
- java – 如何迭代MultiKeyMap?
- jar包启动失败 java Name or service not known解
- java – 使用TransferHandler拖动JLabel(拖放)
- Java 6 NTLM代理身份验证和HTTPS – 有人有工作吗
- Java获取时间差(天数差,小时差,分钟差)代码示例
- java – 为什么catalina.home_IS_UNDEFINED目录是
- java – SWT文本字段设置和绑定到密钥的RCP命令
- 使用PreparedStatement的getGeneratedKeys()无法