Вызываемый как функциональный интерфейс с лямбдами

#java #lambda #java-8 #void #callable

#java #лямбда #java-8 #пустота #вызываемый

Вопрос:

Я только узнаю о новых функциях java8. И вот мой вопрос:

Почему его нельзя использовать Callable<Void> в качестве функционального интерфейса для лямбда-выражений? (Компилятор жалуется на возвращаемое значение) И его использование по-прежнему совершенно законно Callable<Integer> . Вот пример кода:

 public class Test {
    public static void main(String[] args) throws Exception {
        // works fine
        testInt(() -> {
            System.out.println("From testInt method"); 
            return 1;
        });

        testVoid(() -> {
            System.out.println("From testVoid method"); 
            // error! can't return void?
        });
    }

    public static void testInt(Callable<Integer> callable) throws Exception {
        callable.call();
    }

    public static void testVoid(Callable<Void> callable) throws Exception {
        callable.call();
    }
}
  

Как объяснить такое поведение?

Комментарии:

1. не могли бы вы использовать Runnable here вместо этого, если у вас нет возвращаемого значения? (Я еще не знаком с Java8)

2. @Thilo: Одним из преимуществ использования Callable является то, что он возвращает Future, который позже можно использовать для других целей, например, для уничтожения задачи, которая выполняется слишком долго.

3. Также вызываемый может вызывать непроверенное исключение, а выполняемый — нет

Ответ №1:

Для Void метода (отличного от void метода) вы должны вернуть null .

Void это просто заполнитель, указывающий, что у вас на самом деле нет возвращаемого значения (хотя конструкция — например, вызываемая здесь — нуждается в нем). Компилятор не обрабатывает его каким-либо особым образом, поэтому вам все равно придется вводить «обычный» оператор возврата самостоятельно.

Комментарии:

1. Умный. Я думал, что он просто не может определить, какой из них он должен вызывать, и статические функции должны быть общими для предоставления параметра для вызываемого, но я думаю, что нет. Каждый день вы узнаете что-то новое.

2. Да, приятно. return null работает нормально, но простой return оператор этого не делает, и я не могу понять почему.

3. Компилятор не обрабатывает Void подобное void . Он обрабатывает его как любой другой класс, поэтому вам нужно вернуть некоторый экземпляр Void (которого нет), или, в противном случае, null .