我在新编译的课程上得到java.lang.VerifyError
。我尝试使用-Xverify:none
导致java.lang.IncompatibleClassChangeError
的结果。我终于决定反编译我的编译类并得到一个非常意想不到的结果。
原始lambda源(略微改为相关部分)
// field
private final Set<MediaPoolContainerModel> currentModels = Collections.synchronizedSet(new HashSet<>());
//within method
for (final ContainerModel container : containers) {
if (container.isMandatory()) {
currentModels.add(container);
}
final Component component = createComponentForContainer(container, checkEvent -> {
if (checkEvent.isChecked()) {
currentModels.add(container);
} else {
currentModels.remove(container);
}
editorListener.onValueChanged(currentModels);
});
}
EventListener接口(由lambda在这里实现)如下所示:
@FunctionalInterface
public interface EventListener<T extends Event> {
void onEvent(T event) throws Exception;
}
现在,我真的感到惊讶。反编译的类输出:
while(var11.hasNext()) {
ContainerModel container = (ContainerModel)var11.next();
if (container.isMandatory()) {
this.currentModels.add(container);
}
Component component = createComponentForContainer(container, (checkEvent) -> {
if (checkEvent.isChecked()) {
this.currentModels.add(editorListener);
} else {
this.currentModels.remove(editorListener);
}
checkEvent.onValueChanged(this.currentModels);
});
}
您可以观察到,尽管在源代码中使用了捕获container
,但它不再位于lambda中。 editorListener
(其开头的类型完全不同)用于它的位置。 IncompatibleClassChangeException
的原因现在很明显,因为在onValueChanged
而不是checkEvent
上调用了editorListener
。
这是一个严重的编译器错误,如果是这样,有没有人知道原因可能是什么以及如何重现?是否有错误票?我还可以采取哪些措施来调查此问题吗?或者我做了一个我刚才不知道的明显错误?
切换到匿名类确实可以防止这个问题,但我发现在使用lambda时发现这种情况的原因仍然很有趣。
使用java1.8.0_161构建