关于 Java lambda 相等和/或实例化

2022-09-04 03:43:49

为什么下面的代码段在第二次通过时打印为 true?它不应该是一个新实例吗?

import java.util.function.Supplier;

public class Foo {
    public static void main(String[] args) throws Exception {
        Supplier<Long> old = () -> System.nanoTime();

        for (int i = 0; i < 3; i++) {
            /* false true true
            Supplier<Long> foo = System::nanoTime;*/

            Supplier<Long> foo = () -> System.nanoTime();

            /* false false false
            Supplier<Long> foo = new Supplier<Long>() {
                @Override
                public Long get() {
                    return System.nanoTime();
                }
            };
            //*/

            System.out.printf("%s %s %s%n", foo == old, foo, old);

            old = foo;
        }
    }
}

false Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$1/1534030866@133314b
true Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$2/122883338@1ddc4ec2
true Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$2/122883338@1ddc4ec2

答案 1

查看这篇关于如何实现 lambdas 的文章

从本质上讲,编译器将你的两个方法变成了类上的以下静态方法:System.nanoTime()

static Long lambda$1() {
    return System.nanoTime();
}

static Long lambda$2() {
    return System.nanoTime();
}

然后创建一个对每个目标类型的常量引用,以使用 LambdaMetaFactory。坦率地说,我感到失望的是,Java编译器没有意识到lambda主体是相同的,只创建了一个实例。如果Java编译器足够聪明,那么每一行都应该打印出来!Supplier<Long>true


答案 2

推荐