2016-07-26 2 views
2

Я небрежно работал над одним из моих проектов в своей IDE, IntelliJ. Он вообще не обнаружил ошибок, но как только я скомпилировал, появилась ошибка, которая не позволила мне создать проект.Java 8 Stream - Compiler Issue

Я сначала попытался обновить свой JDK, потому что я все еще был в обновлении 65. Я обновил до последней доступной версии (которая была u101 в то время) без везения: проблема все еще была там. Это соответствующий код:

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

код, который не был сбор был частью окружающего .forEach (результат :: добавить). Результат объявляется и инициализируется в этой строке:

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

И дескриптор метода getCommandHandler в:

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

ошибка, произошедшей во время компиляции:

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) 

Я попробовал несколько вещей, чтобы увидеть, если это повлияет на все:

  • Сопоставьте поток, используя листинг (CommandHandler.class :: cast), не исправило проблему
  • Удалите ссылку на метод и замените ее обычным вызовом метода (val -> result.add (val)). Также не исправить это
  • В качестве окончательной опции я использовал вызов метода и casted 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 по переменной исправил его, спасибо за рекомендации! –