2015-02-20 1 views
5

КодексаLambda умозаключения типа выводит исключение типа не брошенная лямбда

class TestException extends Exception { 

} 

interface Task<E extends Exception> { 
    void call() throws E; 
} 

public class TaskPerformer { 

    /** performs a task in the proper context, rethrowing any exceptions the task declares */ 
    private <E extends Exception> void perform(Task<E> task) throws E { 
     beforeTask(); 
     try { 
      task.call(); 
     } finally { 
      afterTask(); 
     } 
    } 

    private void afterTask() { 
     // implementation elided (does not matter) 
    } 

    private void beforeTask() { 
     // implementation elided (does not matter) 
    } 

    public static void main(String[] args) { 
     new TaskPerformer().perform(() -> {  // compilation error 
      try { 
       throw new TestException(); 
      } catch (TestException e) { 
       return; 
      } 
     }); 
    } 
} 

отвергается затмение компилятора с ошибкой

Unhandled типа исключения TestException

в первая строка main, хотя выражение лямбда обрабатывает это исключение (правильно?).

Является ли это ошибкой компилятора, или я что-то пропускаю?

+4

Кажется, это ошибка в 'Eclipse'. Jdk скомпилирует ваш код без проблем. – Holger

+0

@ Хольджер, тот же результат здесь с Oracle JDK 1.8.0_31. meriton, вы проверили открытые ошибки в Eclipse? – ThanksForAllTheFish

+0

Я думал, что значение 'E' в' perform' будет 'Exception', но оно выводится в' RuntimeException', когда исключенное исключение не выбрасывается из лямбда. Не видел, чтобы ошибка говорила «TestException». –

ответ

5

Было обнаружено множество ошибок в последних выпусках Eclipse (а также javac, IntelliJ и т. Д.) Относительно лямбда-выражений и вывода типа. Только сегодня я зарегистрировал 460511, 460515 и 460517. Например, там было довольно много исправлений вокруг комбинации лямбда-выражений и типов исключений только в этом выпуске:

у меня нет проблемы с которой вы столкнулись в Eclipse, 4.5.0 M5 (без javac build 1.8.0_40-ea-b21), поэтому я беру пари, что это ошибка, и она исправлена.

Как правило, если вы используете Java 8 с Eclipse, обновите до последней версии Mars (4.5.0). Всегда. Это избавит вас от множества головных болей.

+0

Спасибо за эту ссылку. Действительно, многие комментарии по этому вопросу относятся к необходимости проведения полного анализа потока, чтобы определить исключения, которые может выбросить лямбда. Такой анализ действительно обнаружит, что моя лямбда не бросает TestException, вызывая исключение RuntimeException. Рад слышать, что ошибка исправлена ​​в более новых версиях, мы рассмотрим обновление. – meriton

Смежные вопросы