我发现从附带的lambda表达式访问类的最后一个字段时无法解释的行为。这是示例程序:
this.<field>
显然,有可能访问一个类的最后一个字段,该字段在构造函数中初始化,然后在lambda表达式中实际初始化
get<Field>()
<field>
。另一方面,通常只能在lambda表达式中引用this
来访问此类 final 字段。我想,lambda中的<field>
总是引用封闭的类,因此this.<field>
和<field>
实际上是相同的。
为了完成混淆,这一切仅适用于最终字段,在构造函数中初始化。对于在声明中初始化的非final字段或final字段, @Test
public void testDispatcher() throws Exception {
User user = userDao.findByLogin("log1");
String sRole = user.getRole().getName();
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(sRole));
UsernamePasswordAuthenticationToken userDetails =
new UsernamePasswordAuthenticationToken(user.getLogin(), user.getPassword(),authorities);
TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(userDetails, null,authorities);
SecurityContextHolder.getContext().setAuthentication(testingAuthenticationToken);
mockMvc.perform(post("/dispatcher")
.principal(testingAuthenticationToken))
.andExpect(status().isOk());
}
完全可以访问,并在lambda调用时使用字段的值。
这里发生了什么?这是lambda表达式定义/引擎的一般缺点,特定Java版本(8u66)中的错误还是仅仅是一个功能?我有点不解。我错了什么?
答案 0 :(得分:1)
对象初始值设定项(即表单字段的声明=类中的值)按照出现的顺序在构造函数之前运行。因此,第一个声明所有访问字段已经在那时初始化,而在构造函数中创建的字段只会在之后初始化相应的对象初始值设定项。
答案 1 :(得分:0)
this.constructorFinalField
是Eclipse Photon中的错误。从而减少了不一致。