Reputation: 4569
If I have a method foo(Predicate bar)
, I can use it next:
foo(new Predicate<MyObject>() {
public boolean apply(MyObject obj) {
return true;
}
}
)
But how can I reach the same result using lambda-style expressions:
foo((MyObject obj) -> true); //obvious compile exception
How can I pass generic type with lambda into the method? Or, simply, how can I create anonymous object of class Predicate(or others) using lambda-style without local variables.
Upvotes: 1
Views: 5097
Reputation: 298103
If your target type is a raw type like in your invocation of foo(Predicate bar)
, you can’t expect lambda expressions to magically generate an appropriate type for you. It works with the anonymous inner class, because that declaration has an explicit type (Predicate<MyObject> {}
) which can get passed to Predicate
in an unsafe operation. But lambda expressions have no type. They are converted to a target type and in your invocation, the target type is Predicate
.
If you want to create a Predicate<MyObject>
via lambda expression, you need Predicate<MyObject>
as it’s target type:
Predicate<MyObject> p = o -> /* note that o has the type MyObject */true;
foo(p);
or
foo((Predicate<MyObject>)o -> /* here, o has the type MyObject as well*/true);
or
void fooHelper(Predicate<MyObject> p) {
foo(p);
}
…
fooHelper(o -> /* here, o has again the type MyObject*/true);
Of course, in all these cases, you could also write (MyObject o) -> true
, but this explicit declaration of the parameter has no influence on the type of the instance created with this lambda expression.
Note that the second variant has the formal structure of a type cast, but there won’t be a type cast operation at runtime. It’s only there for specifying the target type for the lambda expression (similar to widening casts used to select a particular overload in a method invocation).
Upvotes: 1
Reputation: 2382
Don't use raw types foo(Predicate<? extends MyObject> bar)
Or cast inside lambda foo(obj -> ((MyObject) obj).myMethod())
Upvotes: 3