Невозможно преобразовать функциональный интерфейс с помощью универсального метода в лямбда-выражение

Невозможно преобразовать функциональный интерфейс с помощью универсального метода в лямбда-выражение.
Следующий код работает. Это без лямбда-выражения, то есть с использованием анонимного класса.

public interface Pro{
    public <T> void callee(T t);
}

public void fun(Pro obj){}


public void implement() {
    fun(new Pro() {
        @Override
        public <Integer> void callee(Integer t){}
    });
}

Я не могу понять, как использовать лямбда-выражение вместо анонимного класса.
Попробовав сам, я использовал подсказку, показанную в netbeans. Я использовал показанную лампочку, чтобы сделать это.

И вот что я получил, ОШИБКА.

public void implement() {
    fun((Integer t) -> {
    });
}

Это показывает ошибку. Какое правильное лямбда-выражение будет использоваться здесь?
Вот ошибка:

one\LambdaScopeTest.java:18: error: incompatible types: invalid functional descriptor for lambda expression
    fun((Integer t) -> {
        ^
method <T>(T)void in interface Pro is generic
where T is a type-variable:
     T extends Object declared in method <T>callee(T)
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get
full output

1 ответ

Решение

Основная проблема в том, что у вас есть универсальный метод вместо универсального интерфейса. Это не имеет большого смысла. Как только вы сделаете интерфейс универсальным, он будет работать:

@FunctionalInterface
interface Pro<T> {
    void callee(T t);
}

public class Test {    
    public static <T> void fun(Pro<T> obj){}

    public static void main(String[] args) {
        fun((Integer t) -> {});
    }
}

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

Ваша оригинальная версия работает только потому, что вы объявляете параметр общего типа с именем Integer... вы не указываете реализацию для Integer тип. Другими словами, это:

fun(new Pro() {
    @Override
    public <Integer> void callee(Integer t){}
});

эквивалентно:

fun(new Pro() {
    @Override
    public <T> void callee(T t){}
});

... и я не знаю способа представить это как лямбда-выражение. По сути, я думаю, что ваш оригинальный интерфейс не подходит для лямбда-выражений.

Другие вопросы по тегам