Есть ли способ генерировать лямбда? - PullRequest
0 голосов
/ 08 апреля 2019

Я пытаюсь написать лямбду, которая будет реализовывать @FunctionalInterface (BiFunction в этом примере) и будет возвращать объект, сгенерированный с <T>.

Я могу сделать это со старым подходом, объявляющим обобщенный класс (см. class Extractor<T>), но я не понимаю, как это сделать с лямбда-выражением.Единственное, что я могу сделать, - это объявить лямбду с «неизвестным» <?> универсальным типом.

По сути, я хочу объявить лямбду, которую можно передать на method2.Возможно ли это?

private BiFunction<String, Root<Employee>, Path<?>> extractorLambda = 
    (fieldName, root) -> root.get(fieldName);

class ExtractorClass<T> implements BiFunction<String, Root<Employee>, Path<T>> {
    @Override
    public Path<T> apply(final String fieldName, final Root<Employee> root) {
        return root.get(fieldName);
    }
}

private Specification<Employee> method1(String fieldName,
                                        BiFunction<String, Root<Employee>, Path<?>> extractor) {
    return null;
}

private <T> Specification<Employee> method2(String fieldName,
                                            BiFunction<String, Root<Employee>, Path<T>> extractor) {
    return null;
}


public void main(String[] args) {
    method1("s", extractorLambda); // ok
    method2("s", extractorLambda); // error
    ExtractorClass<String> extractorClass = new Extractor<>();
    method2("s", extractorClass);               // ok
}

1 Ответ

1 голос
/ 08 апреля 2019

Проблема в том, что разница между <T> и <?>.

Ваш метод2 ожидает Список объектов одного типа. <?> - это неограниченный подстановочный знак, который означает, что он может содержать все, что угодно, до тех пор, пока он расширяет объект.

То же самое относится и в другом направлении. Если вы попытаетесь использовать ваш класс Extractor с method1, он не скомпилируется, потому что класс говорит, что он работает только для списков определенного типа.

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

    private interface E2<T> extends BiFunction<String, Root<Employee>, Path<T>>{}
    private static final E2 EXTRACTOR = (fieldName, root) -> root.get(fieldName);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...