Как работает java lambdas внешние ссылки? - PullRequest
1 голос
/ 28 февраля 2020

Мне интересно, как работают внешние ссылки на лямбды. Позвольте мне объяснить:

Предположим, у меня есть реализация этого поставщика и класс этой модели:

public class TestSupplierImpl implements Supplier<Boolean> {

    public Predicate<Integer> predicate;
    public TestSupplierModel model;

    public TestSupplierImpl() {
        this.predicate = i -> model.something.equals(i);
    }

    @Override
    public Boolean get() {
        return predicate.test(3);
    }
}


    class TestSupplierModel {
        public Integer something;

        public TestSupplierModel(Integer something) {
            this.something = something;
        }
    }

Затем я выполняю следующий код:

    TestSupplierImpl test = new TestSupplierImpl(); // line 1
    test.model = new TestSupplierModel(3); // line 2
    Boolean resultado = test.get(); // line 3

Строка 1: создание новый экземпляр TestSupplierImpl. Предикат этого нового экземпляра имеет нулевую ссылку модель . Это имеет смысл, потому что в момент создания предиката ссылка на модель является нулевой. Строка 2: присвойте переменной модель новый экземпляр TestSupplierModel. Строка 3: test.predicate теперь имеет ссылку модель с новым присвоенным значением. Почему это так?

Я не понимаю, почему, когда я изменил ссылку модель , предикат обновляет свою ссылку на модель на новую. Как это?

Заранее спасибо!

1 Ответ

1 голос
/ 28 февраля 2020

Имеет ли смысл, если вы переписали свой конструктор TestSupplierImpl() следующим образом?


    public Predicate<Integer> predicate;
    public TestSupplierModel model;

    public TestSupplierImpl() {
        // same effect as this.predicate = i -> model.something.equals(i);
        this.predicate = new Predicate<Integer>() {
            public boolean test(Integer i) {
                return model.something.equals(i);
            }
        };

    }

    @Override
    public Boolean get() {
        return predicate.test(3);
    }

Так что здесь порядок вещей.

        // the constructor is run and the test method defined BUT NOT executed.
        TestSupplierImpl test = new TestSupplierImpl(); // line 1

        // Now you define model
        test.model = new TestSupplierModel(3); // line 2

        // Then you execute the predictate via get()
        Boolean resultado = test.get(); // line 3


model and something не так требуется, пока вы не выполните метод get(). К этому времени они уже определены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...