4

当属于变量的方法的引用被销毁时会发生什么?

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);
4

2 回答 2

11

范围是一个编译时概念,它控制源代码中名称的使用位置。来自 JLS

声明的范围是程序的区域,在该区域内,声明所声明的实体可以使用简单名称来引用,前提是它是可见的(第 6.4.1 节)。

hey名称仅限于标记语句的主体这一事实与运行时whatsGonnaHappen引用的实例是否是垃圾收集的候选对象没有任何关系hey(我认为这是您所担心的)。

关于变量捕获,是的,方法引用hey::square是对特定对象的实例方法的引用(由 引用的方法),因此在评估方法引用表达式以生成实例并使用它时hey将捕获变量的值hey何时apply被调用。

于 2015-10-07T21:25:13.170 回答
2

您的方法参考基本上等同于这样做:

Hey hey = new Hey();
Function<Double, Double> square = new DoubleDoubleFunction(hey);

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 转换为匿名/静态嵌套/内部类,以查看发生了什么。我觉得这是一件很有启发性的事情。

于 2015-10-07T21:29:04.437 回答