なぜlambda式でVariableを使うのはfinalか効果的にfinalなのでしょうか?


平和発展の時期、Variable used in lambda expression should be final or effectively finalという名前のエラーが発生しました.
もっと詳しく説明するなら、品切れの商品は後回しにするため、販売ロジックを立てています.品切れの商品であれば、最大の商品ID+1+の順に後ろに並べ替えることができるため、コード作成時にエラーが発生します.
サンプルコード
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class test {
    public static void main(String[] args) {
        List<Long> productList = new ArrayList<>();
        
        int quantity = 10000;
        quantity ++;

        productList.stream().sorted(Comparator.comparing(b->b + quantity)).collect(Collectors.toList());
    }
}

ううう
解釈から見れば、これは람다 식에 사용되는 변수는 최종 변수이거나 사실상 최종 변수여야 합니다.を意味する.解析内容によると、そこでCopy'm to finaltemp変数を押すと、Ramdaで使用したい変数をコピーし、エラーを解決する変数を作成できます.
しかし、なぜRamdaで使われる変数が最終変数(final)でなければならないのか、あるいは事実上最終変数(実際にはfinal)でなければならないのか???

ランダ捕獲


パラメータ外で定義された変数を自由変数(Free Variable)と呼び,Ramda本体で自由変数を参照する挙動をRamda切り取りと呼ぶ.

Ramdaキャプチャの制約


領域変数を取得する場合、対応する変数はfinalまたはeffectでなければなりません.理由は次のとおりです.
制約が地域変数にのみ適用される理由
領域変数はJVMのスタック領域で作成され、スタック領域はスレッドごとに個別の領域を作成するので、Thread間は共有されません.
インスタンス変数はJVMのhip領域で作成され、hip領域は別々の領域で作成されるので、Thread間で共有できます.
したがって、スクリーンショットは、地域変数の場合にのみ使用されます.
ランダは単独のThreadで動作することができる.
元の領域変数のあるThreadが消失し、その領域変数も消失したが、実行中のThreadが実行されている可能性がある.
しかし、ラムダは変数を自分のThreadにコピーして使うので、間違いはありません.
したがって、コピーされた変数は変更を続行できないため、final(最終変数)または有効final(実際には最終変数)でなければなりません.

🙇🏼‍♀️ リファレンス


なぜInner class、Lambdaはfinalに効率的にアクセスできるのか。
(Java)Ramdaキャプチャとfinal制約