功能接口和方法引用的行为
Behavior of Functional Interface and Method Reference
当属于变量的方法引用被销毁时会发生什么?
public class Hey{
public double bar;
public Hey(){
bar = 2.0d;
}
public double square(double num){
return Math.pow(num , bar);
}
}
Function<Double, Double> square;
whatsGonnaHappen: {
Hey hey = new Hey();
square = hey::square;
}//is hey still kept around because its method is being referenced?
double ans = square.apply(23d);
作用域是一个编译时概念,它控制源代码中名称的使用位置。 From the JLS
The scope of a declaration is the region of the program within which
the entity declared by the declaration can be referred to using a
simple name, provided it is visible (§6.4.1).
名称 hey
仅限于 whatsGonnaHappen
标记语句的主体这一事实与 hey
在运行时引用的实例是否是垃圾收集的候选人(我想这就是你担心的)。
关于变量捕获,是的,方法引用hey::square
是对特定对象(hey
引用的对象)的实例方法的引用,因此将捕获当评估方法引用表达式以生成实例并在调用 apply
时使用它时变量 hey
。
您的方法参考基本上等同于这样做:
Hey hey = new Hey();
Function<Double, Double> square = new DoubleDoubleFunction(hey);
其中 class DoubleDoubleFunction
是这样定义的
class DoubleDoubleFunction implements Function<Double, Double> {
private final Hey hey;
public DoubleDoubleFunction(Hey hey) {
this.hey = hey;
}
@Override
public Double apply(Double num) {
return hey.square(num);
}
}
换句话说,square
持有对 Hey
的引用。
我不知道 eclipse,但使用 IntelliJ,您可以轻松地将方法引用和 lambda 转换为匿名/静态嵌套/内部 classes 以查看发生了什么。我发现这是一件很有启发性的事情。
当属于变量的方法引用被销毁时会发生什么?
public class Hey{
public double bar;
public Hey(){
bar = 2.0d;
}
public double square(double num){
return Math.pow(num , bar);
}
}
Function<Double, Double> square;
whatsGonnaHappen: {
Hey hey = new Hey();
square = hey::square;
}//is hey still kept around because its method is being referenced?
double ans = square.apply(23d);
作用域是一个编译时概念,它控制源代码中名称的使用位置。 From the JLS
The scope of a declaration is the region of the program within which the entity declared by the declaration can be referred to using a simple name, provided it is visible (§6.4.1).
名称 hey
仅限于 whatsGonnaHappen
标记语句的主体这一事实与 hey
在运行时引用的实例是否是垃圾收集的候选人(我想这就是你担心的)。
关于变量捕获,是的,方法引用hey::square
是对特定对象(hey
引用的对象)的实例方法的引用,因此将捕获当评估方法引用表达式以生成实例并在调用 apply
时使用它时变量 hey
。
您的方法参考基本上等同于这样做:
Hey hey = new Hey();
Function<Double, Double> square = new DoubleDoubleFunction(hey);
其中 class DoubleDoubleFunction
是这样定义的
class DoubleDoubleFunction implements Function<Double, Double> {
private final Hey hey;
public DoubleDoubleFunction(Hey hey) {
this.hey = hey;
}
@Override
public Double apply(Double num) {
return hey.square(num);
}
}
换句话说,square
持有对 Hey
的引用。
我不知道 eclipse,但使用 IntelliJ,您可以轻松地将方法引用和 lambda 转换为匿名/静态嵌套/内部 classes 以查看发生了什么。我发现这是一件很有启发性的事情。