将lambda作为参数传递给generics类型 – java 8
如果我有方法foo(Predicate bar)
,我可以使用下一个:
foo(new Predicate() { public boolean apply(MyObject obj) { return true; } } )
但是如何使用lambda样式表达式获得相同的结果:
foo((MyObject obj) -> true); //obvious compile exception
如何将带有lambda的generics类型传递给方法? 或者,简单地说,如何使用没有局部变量的lambda样式创建类Predicate(或其他)的匿名对象。
不要使用原始类型foo(Predicate extends MyObject> bar)
或者在lambda foo(obj -> ((MyObject) obj).myMethod())
如果你的目标类型是一个原始类型,就像调用foo(Predicate bar)
,你不能指望lambda表达式为你神奇地生成一个合适的类型。 它适用于匿名内部类,因为该声明具有显式类型( Predicate
),它可以在不安全的操作中传递给Predicate
。 但是lambda表达式没有类型。 它们被转换为目标类型,在您的调用中,目标类型是Predicate
。
如果要通过lambda表达式创建Predicate
,则需要Predicate
作为目标类型:
Predicate p = o -> /* note that o has the type MyObject */true; foo(p);
要么
foo((Predicate)o -> /* here, o has the type MyObject as well*/true);
要么
void fooHelper(Predicate p) { foo(p); } … fooHelper(o -> /* here, o has again the type MyObject*/true);
当然,在所有这些情况下,您也可以编写(MyObject o) -> true
,但是这个参数的显式声明对使用此lambda表达式创建的实例的类型没有影响。
请注意,第二个变体具有类型转换的正式结构,但在运行时不会有类型转换操作。 它仅用于指定lambda表达式的目标类型(类似于用于在方法调用中选择特定重载的扩展转换)。