Sobes.tech
Middle

Ի՞նչ հիմք ունեն լամբդա արտահայտությունները։

sobes.tech AI

Պատասխան AI-ից

Աշխատում է Invoke Dynamic (JSR 292) մեխանիզմի վրա։ Դա թույլ է տալիս հետաձգել մեթոդների կանչերի լուծումը մինչև գործարկման պահը։ Սա դարձնում է լամբդաները ավելի ճկուն և արդյունավետ, քան պարզ ֆունկցիոնալ ինտերֆեյսների համար անանուն ներքին դասերի օգտագործումը։

Java կոմպիլյատորը փոխակերպում է լամբդա արտահայտությունը հատուկ կառուցվածքի, որը օգտագործում է lambda$() անվամբ ստատիկ մեթոդը, որը կանչվում է invokedynamic-ի միջոցով։

Օրինակ՝

// Ֆունկցիոնալ ինտերֆեյս
interface MyFunctionalInterface {
    void myMethod();
}

// Լամբդայի օգտագործում
public class LambdaExample {
    public static void main(String[] args) {
        MyFunctionalInterface myLambda = () -> System.out.println("Բարև լամբդայից!");
        myLambda.myMethod();
    }
}

Կոմպիլյացիայից հետո, լամբդայով կոդը մոտավորապես այսպես կթողնվի (bytecode-ում):

  invokedynamic #0:myMethod:()V()LI; // BootstrapMethod:lambda$0
  astore_1
  aload_1
  invokeinterface MyFunctionalInterface.myMethod:()V interface 1

Bootstrap մեթոդը (սկզբնական բեռնումի մեթոդը) որոշում է, թե որ մեթոդը կանչել։ Լամբդայի դեպքում դա սովորաբար java.lang.invoke.LambdaMetafactory.metafactory(), որը ժամանակի ընթացքում ստեղծում է ֆունկցիոնալ ինտերֆեյսի դասը և օրինակն, կապելով այն լամբդայի իրականացման հետ (այս դեպքում՝ lambda$0 ստատիկ մեթոդը):

Այս մոտեցումը նվազեցնում է մի շարք անանուն ներքին դասերի ստեղծման ծախսերը, բարելավում է կատարողականությունը և հիշողության օգտագործումը, հատկապես հավաքածուներում և հոսքերում։