Подтвердить что ты не робот

О явном равенстве Java и/или экземпляре

Почему снимок ниже print 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/[email protected] Foo$$Lambda$1/[email protected]
true Foo$$Lambda$2/[email protected] Foo$$Lambda$2/[email protected]
true Foo$$Lambda$2/[email protected] Foo$$Lambda$2/[email protected]
4b9b3361

Ответ 1

Посмотрите article о том, как реализованы лямбды.

По сути, компилятор превратил ваши два System.nanoTime() в следующие статические методы в вашем классе:

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

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

И затем создайте постоянную ссылку на каждую целевую строку, указанную на Supplier<Long>, используя LambdaMetaFactory. Честно говоря, я разочарован тем, что компилятор Java не понял, что тело лямбда было идентичным и только создало один экземпляр. Если компилятор Java был достаточно умным, каждая строка должна была напечатать true!