Почему невозможно реализовать функциональный интерфейс с использованием лямбда-выражения вне класса?

#java #lambda

#java #лямбда

Вопрос:

Функциональный интерфейс можно реализовать таким образом:

 abstract class predicate implements Predicate<Integer> {

    public static boolean test(int e) {
        return true;
    }
}

 

или таким образом:

 Predicate<Integer> predicate = e -> true;
 

Следующий код компилируется:

 import java.util.function.*;


abstract class predicate implements Predicate<Integer> {

    public static boolean test(int e) {
        return true;
    }
}

public class Main
{
    public static void main(String[] args) {
        System.out.println(predicate.test(2));
    }
}

 

Но этот код этого не делает и выдает ошибку «класс, интерфейс или ожидаемое перечисление»:

 import java.util.function.*;

Predicate<Integer> predicate = e -> true;

public class Main
{
    public static void main(String[] args) {
        System.out.println(predicate.test(2));
    }
}

 

Чтобы приведенный выше код работал, мне пришлось бы реализовать интерфейс внутри основного класса. Почему?

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

1. Весь код (без импорта) должен находиться в объявлении класса. Именно так был разработан язык.

2. Вы не можете объявить автономную переменную любого типа в Java. Все переменные находятся внутри класса / интерфейса.

3.@lostperson. Predicate<Integer> predicate = e -> true; predicate является переменной. Но почему вы спрашиваете об этом? Это ничем не отличается от вопроса, почему методы или поля чувствительны к регистру. Язык либо допускает это, либо нет.

4. И вы не одиноки в этом вопросе. Но у меня на самом деле больше вопросов об исключении определенных функций в API, чем у компилятора.

5. Predicate<Integer> predicate является переменной типа Predicate<Integer> . Он содержит один объект. Это функционально не эквивалентно объявлению типа.

Ответ №1:

Поля (даже постоянные поля) должны быть определены в классе, и здесь вы используете его так, как будто ожидаете, что это будет статическая константа. Нравится,

 public class Main {
    private static final Predicate<Integer> predicate = e -> true; // PREDICATE by convention

    public static void main(String[] args) {
        System.out.println(predicate.test(2));
    }
}