在Java8中,以下语句“lambda是没有标识的对象”背后的背景是什么?
如果您能帮助理解Java8中的以下两个概念,我们将不胜感激 我所知道的 lambda是没有标识的对象,不应用作常规对象。 lambda表达式不应该从对象类(如toString、equals、hashCode等)调用方法。 我想知道更多关于 lambda表达式作为没有标识的对象调用有什么区别 为什么在使用lambda表达式时不使用Objectclass中的方法在Java8中,以下语句“lambda是没有标识的对象”背后的背景是什么?,java,Java,如果您能帮助理解Java8中的以下两个概念,我们将不胜感激 我所知道的 lambda是没有标识的对象,不应用作常规对象。 lambda表达式不应该从对象类(如toString、equals、hashCode等)调用方法。 我想知道更多关于 lambda表达式作为没有标识的对象调用有什么区别 为什么在使用lambda表达式时不使用Objectclass中的方法 基本上,lambda是这样做的一种便利: @FunctionalInterface interface A { void b();
基本上,lambda是这样做的一种便利:
@FunctionalInterface
interface A {
void b();
}
void c(A a) {
...
}
void main() {
c(new A() {
void b() {
...
}
});
}
我为不太重要的变量名道歉,但正如您所看到的,A是一个带有一个方法的接口。c是一种接受接口的方法。但是,您可以当场创建它,而不是创建自己的类来实现。这就是所谓的匿名类,因为它没有名称。这就是您的报价:
A lambda is an object without an identify
来自。该类没有标识。它与lambdas相关的原因是,如果接口只有一个方法,那么可以使用lamdas来简化它
void main() {
c(
() -> {
...
}
);
}
这和以前一模一样
第二部分,为什么lambdas不应该使用Object的方法,我以前不知道。您可能应该让其他人回答这个问题,但是我的猜测是lambda类看起来不像是直接扩展对象,所以您不能使用它的方法。基本上,lambda是这样做的一种便利:
@FunctionalInterface
interface A {
void b();
}
void c(A a) {
...
}
void main() {
c(new A() {
void b() {
...
}
});
}
我为不太重要的变量名道歉,但正如您所看到的,A是一个带有一个方法的接口。c是一种接受接口的方法。但是,您可以当场创建它,而不是创建自己的类来实现。这就是所谓的匿名类,因为它没有名称。这就是您的报价:
A lambda is an object without an identify
来自。该类没有标识。它与lambdas相关的原因是,如果接口只有一个方法,那么可以使用lamdas来简化它
void main() {
c(
() -> {
...
}
);
}
这和以前一模一样
第二部分,为什么lambdas不应该使用Object的方法,我以前不知道。您可能应该让其他人回答这个问题,但我的猜测是lambda类看起来不像是直接扩展对象,所以您不能使用它的方法
1 lambda是没有标识的对象,不应用作常规对象
事实并非如此。lambda是一个Java对象,它确实具有标识1。问题是故意将生命周期留待指定,以允许Java编译器自由地优化对其求值的代码。因此,您无法知道何时创建新的lambda对象,或者何时重用现有的lambda对象
JLS表示:
在运行时,lambda表达式的求值与类实例创建表达式的求值类似,只要正常完成生成对对象的引用。lambda表达式的计算不同于lambda体的执行
分配并初始化具有以下属性的类的新实例,或者引用具有以下属性的类的现有实例
2 lambda表达式不应调用对象类中的方法,如toString、equals、hashCode等
如文中所述,这也是不正确的。lambda表达式可以调用这些方法。但是,在lambda对象上调用这些方法时,不建议依赖这些方法来实现任何特定行为
联合联络小组指出:
班级。。。可以重写对象类的方法
换句话说,它可能。。。也许不是。。。超越它们。如果您依赖这些方法的特定行为,那么您的应用程序在理论上是不可移植的
此外,由于实例化语义也未指定,Object::equals和Object::hashCode的行为是不确定的
最后,还未确定lambda是否可克隆
1-当然,lambda没有名字:它是匿名的。但是名字和身份是不同的概念
1 lambda是没有标识的对象,不应用作常规对象
事实并非如此。lambda是一个Java对象,它确实具有标识1。问题是故意将生命周期留待指定,以允许Java编译器自由地优化对其求值的代码。因此,您无法知道何时创建新的lambda对象,或者何时重用现有的lambda对象
JLS表示:
在运行时,lambda表达式的求值与类实例创建表达式的求值类似,只要正常完成生成对对象的引用。lambda表达式的计算不同于lambda体的执行
具有以下属性的类的新实例都是
已配置并初始化,或者引用了具有以下属性的类的现有实例
2 lambda表达式不应调用对象类中的方法,如toString、equals、hashCode等
如文中所述,这也是不正确的。lambda表达式可以调用这些方法。但是,在lambda对象上调用这些方法时,不建议依赖这些方法来实现任何特定行为
联合联络小组指出:
班级。。。可以重写对象类的方法
换句话说,它可能。。。也许不是。。。超越它们。如果您依赖这些方法的特定行为,那么您的应用程序在理论上是不可移植的
此外,由于实例化语义也未指定,Object::equals和Object::hashCode的行为是不确定的
最后,还未确定lambda是否可克隆
1-当然,lambda没有名字:它是匿名的。但是名字和身份是不同的概念。嘿!你能解释一下你到底不确定什么吗?这将使问题不那么依赖于某人来解释整件事,而更关注于理解问题。嘿!你能解释一下你到底不确定什么吗?这将使问题不那么依赖于某人来解释整件事,而更关注于理解问题。身份和名字是不同的概念。身份和名字是不同的概念。