2016-07-26 89 views
2

我在我的IDE IntelliJ中随意使用了我的一个项目。它并没有显示任何错误,但是一旦我编译完成,就会弹出一个错误信息,导致我无法构建项目。Java 8 Stream - 编译器问题

我第一次试图更新我的JDK,因为我仍然在更新65.我更新到最新版本(当时是u101),但没有运气:问题仍然存在。这是相关代码:

((List<?>) value).stream().filter(this::isStringOrPrimitive) 
          .map(val -> getCommandHandler(command, plugin, val.toString())) 
          .forEach(result::add); 

未编译的代码是围绕.forEach(result :: add)的部分。结果公布,并在这一行初始化:

List<CommandHandler> result = new ArrayList<>(); 

而且getCommandHandler方法的描述:

Error:(59, 42) java: incompatible types: invalid method reference 
no suitable method found for add(java.lang.Object) 
    method java.util.Collection.add(me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) is not applicable 
     (argument mismatch; java.lang.Object cannot be converted to me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) 
    method java.util.List.add(me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) is not applicable 
     (argument mismatch; java.lang.Object cannot be converted to me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) 
    method java.util.AbstractCollection.add(me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) is not applicable 
     (argument mismatch; java.lang.Object cannot be converted to me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) 
    method java.util.AbstractList.add(me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) is not applicable 
     (argument mismatch; java.lang.Object cannot be converted to me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) 
    method java.util.ArrayList.add(me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) is not applicable 
     (argument mismatch; java.lang.Object cannot be converted to me.megamichiel.animatedmenu.command.CommandExecutor.CommandHandler) 

我试过几件事情,看看:

private <T, C> CommandHandler getCommandHandler(Command<T, C> command, 
               AnimatedMenuPlugin plugin, String str) { 

在编译时发生的错误它会影响任何东西:

  • 使用cast(CommandHandler.class :: cast)映射流,未修复问题
  • 删除方法引用,并用常规方法调用(val - > result.add(val))替换。也没有修复它
  • 作为最后的选择,我使用了方法调用和铸造val到CommandHandler。这解决了这个问题,但我不喜欢我必须手动投射到CommandHandler,而Java可以自己做。

我也可以完全摆脱流,但我想先看看这是否是某种编译器问题,或者如果我做错了什么。谢谢你的时间。

+0

尝试在您的lambdas中使用显式参数类型,并使用泛型方法显式类型参数。然后逐个删除它们以查看问题所在。 – shmosel

回答

0

奇怪的编译器行为。尝试提取初始流并提供类型参数?

Stream<?> stream = ((List<?>) value).stream(); 
stream.filter(this::isStringOrPrimitive) 
    .map(val -> getCommandHandler(command, plugin, val.toString())) 
    .forEach(result::add); 

对于我的代码,它帮助编译器正确推断流水线中其他步骤的类型。

+1

我第一次尝试这个,但不幸的是没有解决问题。我确实使用了外部化的想法,尽管使变量成为Stream ,并一路走到映射之后。然后调用.forEach变量确实修复它,谢谢指导! –