출처: https://tourspace.tistory.com/11?category=788398, https://tourspace.tistory.com/12?category=788398
(자바 컴파일? java 파일이 class 파일로 변환되는 과정. class파일은 byte코드이다.)
설명
- 기존에 바이트코드에서 메쏘드를 표현하기 위해 네종류의 opcode를 사용했었으나, java7부터 invokdeddynamic(indy로 표현) 이 추가되었음.
- invokeddynamic은 java7에서 java가 아니라 jython, groovy 등 jvm에서 돌아가는 다른 언어의 람다식만 지원했던 형태같고, java파일 컴파일된 bytecode에서는 절대 사용되지 않았음.
- 익명클래스는 컴파일시 별도의 class파일을 가지고 당연히 객체형태로 사용되며, 람다는 class파일이 생성되지는 않지만 객체형태로 호출됨.
- 컴파일시에 바이트코드에서는 런타임에 실제 생성을 하는 방법(레시피)만 표기
- 해당 레시피는 invokedynamic instrucion에 의해 동적/정적 인수 목록으로 encoding됨.
- 암턴 bytecode내에서 indy가 호출되면 bootstrap 영역의 lambdafactory.metafactory()를 수행
- lambdafactory.metafactory(): java runtime library의 표준화 method
- 어떤 방법으로 생설할지는 최적화된 방법으로 동적으로 결정된다.
- java.lang.invoke.CallSite 객체를 리턴함
- 해당 람다의 람다 팩토리
- MethodHandle을 멤버변수로 가진다.!
- 사용자가 작성한 람다가 변환되는 함수 인터페이스의 인스턴스를 반환
- 한번만 생성되고 재호출시 재 사용함(이래서 익명클래스보다 빠름.)
- CallSite 내부에는 java.lang.invoke.MethodHandle을 멤버 변수로 갖고, MethodHandle은 람다와 연결된 private method로 연결됨.
- 작성된 람다는 private static method로 형태로 되어 호출됨(desugaring)
- 요약: 작성된 람다는 런타임시에 구현됨.
- 원리 -> 자바컴파일 -> 람다를 만들기 위한 레시피가 포함된 byte코드 생성 -> invokedynamic 지시자가 레시피를 참조하여 CallSite 객체를 리턴함 -> CallSite 의 멤버변수인 MethodHandle이 람다와 연결된 private method로 연결됨 -> 람다식은 desugaring되어 method형태로 되고, 이게 호출되는 방식임.
더 자세히는
자바 최적화 - 가장 빠른 성능을 구현하는 검증된 10가지 기법 책 읽어보는게 나을듯.
슈가, 디슈가링
- Synatic Sugar : 간결하게 표현한다.
- 마치 익명클래스를 람다식으로 표현해서 잡다한 노이즈코드를 걷어내는 것.
- Desugar : sugar된 문장을 원래대로 되돌린다라
- 자바8 내부에서 람다를 해석할 때, 동적으로 슈가된 람다코드를 디슈가링해서 메쏘드 형태로 만들어 놓고, 이 메쏘드가 메쏘드 핸들에 연결되어 호출하는 방식으로 쓴다는 것.
'IT > 자바8-람다' 카테고리의 다른 글
람다 원리 및 값 캡쳐란? (0) | 2020.05.07 |
---|---|
클로져(Closure, Close-over), 쉐도잉 (0) | 2020.05.06 |
Identity 함수? (0) | 2020.04.29 |
자주쓰는 람다 (0) | 2020.04.29 |
람다 사용법 및 규칙 (0) | 2020.04.23 |