I'm trying to write a lambda that will implement a @FunctionalInterface
(BiFunction
in this example) and will return an object generified with <T>
.
I can do it with the old approach declaring a generified class (see class Extractor<T>
), but I do not understand how to do it with lambda. The only thing I am able to do is to declare a lambda with "unknown" <?>
generic type.
Basically, I want to declare a lambda that is possible to pass to method2
. Is it possible?
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
}
答案 0 :(得分:1)
The problem is difference between <T>
and <?>
.
Your method2 expects List of objects of one type. <?>
is unbounded wildcard that means it can contain whatever as long as it extends Object.
Same applies in other direction. If you try to use your Extractor class with method1, it won't compile because class says it works just for lists of certain type.
As far as I know you can't have generic type definition on field. Based on your comment this looks like shortest workaround:
private interface E2<T> extends BiFunction<String, Root<Employee>, Path<T>>{}
private static final E2 EXTRACTOR = (fieldName, root) -> root.get(fieldName);