java8 lambda , 람다 표현식의 동작 이해

java 8의 lambda function을 이용한 람다 표현식의 동작을 이해해보자.

functional interface Consumer 를 익명클래스로 작성하여 사용하면
여타 다른 익명클래스 사용하는 것과 다르지 않다.
컴파일러는 innerClasses 로 익명클래스를 작성하여 참조한다.

하지만 람다표현식으로 작성된것은 어떻게 처리될까?

아래와 같은 소스가 있다.

Image for post
Image for post

Consumer functional interface 를 람다 표현식으로 작성한것이다.
람다 표현식에 대해 컴파일러는 어떻게 처리하는지 바이트코드를 봐보자.

위키피디아 java bytecode instruction을 참고하자.

main method 부분을 일단 정리하자.

0: invokedynamic #2, 0 // InvokeDynamic #0:accept:()Ljava/util/function/Consumer;
- jvm이 invokedynamic #2에서 bootstrapMethods를 통해 지정된
static method com/test/Main.lambda$main$0을 실행시킨다.

5: astore_1
- consumer 라는 이름으로 로컬변수 인덱스1 번에 store한다.

6: aload_1
- 로컬변수 1번에서 스택으로 load한다.

7: ldc #3 // String hello world
- 문자열 hello world 를 스택에 올린다.

9: invokeinterface #4, 2 // InterfaceMethod java/util/function/Consumer.accept:(Ljava/lang/Object;)V
- Consumer interface method accept를 실행한다.

여기서 봐야할것은
invokedynamic에 의해 실행되는 com/test/Main.lambda$main$0이다.

intellij의 byte code viewer 를 통해 보면
선언된 static method를 볼 수 있다.

Image for post
Image for post

람다 표현식 body는 컴파일러에 의해 static method로 작성되고
BootstrapMethods에서 LambdaMetaFactory.metafactory 메소드를 호출하여 static method를 핸들링하는 CallSite를 생성한다.

아래의 소스는 LambfaMetaFactory를 통해 어떻게 lambda expression으로 부터 만들어진 static method로 핸들링 되는지 구현한것이다.

람다 표현식의 본문부분에 해당하는 static method lambdaBody를 작성했다.

bootstrap methods에서 처리하는 부분에 해당하는 lambdaFunction메소드에서는 LambdaMetaFactory.metafactory()를 통해 메소드 핸들링되는 CallSite객체를 생성한다.

CallSite.getTarget().invoke()를 통해 invokeType에 해당하는 Function을 얻을수 있다.

lambdaFunction 메소드는 추론을 통해 리턴타입을 캐스팅하고
Function<String, String> fnc 변수에 의해 참조된다.

fnc.apply() 호출은 lambdaBody메소드를 핸들링하게 된다.

아래는 invokedynamic에 대한 slideshare이다. 영알못이라 눙물이..

흠.슬라이드 45페이지의 호출흐름이 한눈에 보기 좋았다.

45페이지에 작성된 연결관계를 다시 그려보자면 아래와 같다.

Image for post
Image for post

invoke dynamic 에서 bootstrap method를 실행하고 method handles에서 target method 핸들링을 정의한다.

다시 invokedynamic을 만나면 bootstrap method 와 method handles 처리는 생략하고 바로 target metdho를 핸들링한다.

-_- 정리가 잘못된 부분이 있을까 두렵두렵..

참조 :

https://www.slideshare.net/CharlesNutter/invokedynamic-in-45-minutes

https://slipp.net/wiki/pages/viewpage.action?pageId=19530380

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store