Спецификация не делает различий между «ссылками» и «использованием» переменной. В связи с этим вы используете переменную, вызывая t.yield()
, несмотря на то, что вы вызываете метод static
. Для этого сценария в спецификации написано
JLS § 15.12.4.1, 15.12.4.1. Расчет целевого задания (при необходимости) :
- Если форма ExpressionName. [TypeArguments] Идентификатор , затем:
- Если режим вызова
static
, то целевой ссылки нет. ExpressionName оценивается, но результат затем отбрасывается.
- В противном случае целевой ссылкой является значение, обозначаемое ExpressionName .
, поэтому поведение соответствует спецификации.
Хотя очевидно, что оценка должна произойти, когда она имеет побочные эффекты, я бы не пошел так далеко, чтобы заключить, что последовательность байт-кодов ALOAD 0
, GETFIELD
, POP
строго требуется для выполнения формального правила, согласно которому переменная оценивается, а результат отбрасывается, так как этот код не имеет никакого эффекта.
Но независимо от того, присутствуют ли эти инструкции, переменная t
используется и, следовательно, подчиняется формальным требованиям, то есть она должна быть эффективная окончательная .
Должно ли это обязательное поведение приводить к захвату значения в экземпляре внутреннего класса, соответственно класс, сгенерированный для лямбда-выражения, возможно, на удивление, совершенно не указан Спецификация языка Java ничего не говорит об этом.
Другими словами, когда вы спрашиваете о угловом случае захвата значения, то есть значении переменной, на которую ссылаются, но не нужной, даже общем случае, то есть хорошо известном правиле, что внутренние классы всегда сохраняют ссылка на вмещающую this
, даже если она не нужна, в то время как лямбда-выражения нет, нигде не указана в официальной спецификации.