출처: 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

+ Recent posts