将lambda作为泛型类型的参数传递-java 8

将lambda作为泛型类型的参数传递-java 8,java,generics,lambda,java-8,Java,Generics,Lambda,Java 8,如果我有一个方法foo(谓词栏),我接下来可以使用它: foo(new Predicate<MyObject>() { public boolean apply(MyObject obj) { return true; } } ) 如何将带有lambda的泛型类型传递到方法中? 或者,简单地说,我如何使用lambda样式创建类谓词的匿名对象(或其他对象),而不使用局部变量。不要使用原始类型foo(谓词不要使用原始类型f

如果我有一个方法
foo(谓词栏)
,我接下来可以使用它:

foo(new Predicate<MyObject>() {
        public boolean apply(MyObject obj) { 
           return true;
        }
    }
)
如何将带有lambda的泛型类型传递到方法中?
或者,简单地说,我如何使用lambda样式创建类谓词的匿名对象(或其他对象),而不使用局部变量。

不要使用原始类型
foo(谓词不要使用原始类型
foo(谓词如果您的目标类型是原始类型,就像调用
foo(谓词栏)一样)
,您不能期望lambda表达式神奇地为您生成合适的类型。它与匿名内部类一起工作,因为该声明具有显式类型(
谓词{}
)在不安全的操作中,可以将其传递到
谓词
。但是lambda表达式没有类型。它们被转换为目标类型,并且在您的调用中,目标类型是
谓词

如果要通过lambda表达式创建
谓词
,则需要
谓词
作为其目标类型:

Predicate<MyObject> p = o -> /* note that o has the type MyObject */true;
foo(p);
谓词p=o->/*注意,o的类型为MyObject*/true;
富(p),;

foo((谓词)o->/*这里,o的类型也是MyObject*/true);

void fooohelper(谓词p){
富(p),;
}
…
fooHelper(o->/*这里,o的类型再次为MyObject*/true);
当然,在所有这些情况下,您也可以编写
(MyObject o)->true
,但此参数的显式声明对使用此lambda表达式创建的实例的类型没有影响


请注意,第二个变量具有类型转换的正式结构,但在运行时不会有类型转换操作。它仅用于指定lambda表达式的目标类型(类似于用于在方法调用中选择特定重载的加宽转换).

如果您的目标类型是原始类型,就像调用
foo(谓词栏)
时一样,您不能期望lambda表达式神奇地为您生成合适的类型。它与匿名内部类一起工作,因为该声明具有显式类型(
谓词{}
)在不安全的操作中,可以将其传递到
谓词
。但是lambda表达式没有类型。它们被转换为目标类型,并且在您的调用中,目标类型是
谓词

如果要通过lambda表达式创建
谓词
,则需要
谓词
作为其目标类型:

Predicate<MyObject> p = o -> /* note that o has the type MyObject */true;
foo(p);
谓词p=o->/*注意,o的类型为MyObject*/true;
富(p),;

foo((谓词)o->/*这里,o的类型也是MyObject*/true);

void fooohelper(谓词p){
富(p),;
}
…
fooHelper(o->/*这里,o的类型再次为MyObject*/true);
当然,在所有这些情况下,您也可以编写
(MyObject o)->true
,但此参数的显式声明对使用此lambda表达式创建的实例的类型没有影响


请注意,第二个变量具有类型转换的正式结构,但在运行时不会有类型转换操作。它仅用于指定lambda表达式的目标类型(类似于用于在方法调用中选择特定重载的加宽转换).

一些sdk中使用了原始类型,我无法修改它。为什么我要强制转换?我知道,我可以这样做,但如果基本语法提供了使用泛型类型创建lambda的功能,为什么语法糖不提供呢?这意味着,如果我使用谓词类的实例化,我就拥有完整的功能,如果我使用速记语法糖,我失去了一些东西?在匿名内部类中,您通过使其泛型来提供额外的类型信息。这相当于
List List=new ArrayList
。即使使用泛型实现,您也必须在每次
List.get
之后从
对象进行强制转换。编译器不能保证sdk的提供程序不会
测试
y类型为object的谓词不是
MyObject
,如果内部类impl将失败,即使它看起来是类型安全的。在考虑sdk wich使用java8而不是泛型之前,我会三思而后行(延迟)或者至少将其隐藏在外观后面。接收器定义的lambda类型。它始终是泛型的。Raw是泛型的,上界为
对象
。例如
谓词
。lambda使用invoke dynamic实现,通常比anon类更有效。您还可以像这样强制转换lambda表达式
(谓词)obj->…
。这在语义上与您的anon类相同。如果您称之为“功能性”。醒醒。你所做的只是欺骗编译器,让它认为
obj
类型是
MyObject
。这样它在运行时会打到你的脸上。你不能在原始类型上转储泛型。句号。我想这是故意的。好的语言设计的一部分就是让愚蠢的事情至少显式化。原始类型在一些sdk中使用,一个d我不能修改它。为什么我要强制转换?我明白,我可以这样做,但如果基本语法提供了创建泛型类型lambda的功能,为什么语法糖不提供?这意味着,如果我使用谓词类的实例化,我就有了完整的功能,如果我使用速记语法糖,我就失去了一些功能?在匿名内部类通过使其泛型来提供额外的类型信息。这相当于
List List=new ArrayList
。即使使用泛型实现,您也必须在每个
列表之后从
对象
强制转换。获取
。编译器不能保证sdk的提供程序不会
测试类型为no的对象的谓词t
MyObject
以防内部类impl失败,即使它看起来是类型安全的。在考虑使用java8而不是泛型(延迟)的sdk之前,我会三思而后行,或者至少将其隐藏在外观后面。Type
foo((Predicate<MyObject>)o -> /* here, o has the type MyObject as well*/true);
void fooHelper(Predicate<MyObject> p) {
    foo(p);
}
…
fooHelper(o -> /* here, o has again the type MyObject*/true);