studybook
  • Introduction
  • 실무 하며 깨닫는 부분 정리
    • 옵션에 대해서
    • 코드 작성의 순서
    • 자바 프로그램에 문제가 생겼다면
    • 장애 대처법
  • Logstash, Beats 정리
  • Zookeeper 정리
  • Message Queue 정리
    • RabbitMQ 삽질
  • Java 관련 정리
    • Java Primitive Wrapper class
    • Java NIO
    • Java8 Double colon operator
    • Effective Java
      • 4장
      • 5장
      • 6장 - Enum, Annotation
      • 7장 - Method
      • 8장 - 프로그래밍 일반
      • 9장 - Exception
    • Java8 Lambda expression
    • JDBC
    • Linux에서 WatchService 이상동작
  • Spring 관련 정리
    • Spring Bean init, destroy 순서
    • Spring Async Controller
    • Spring Executable jar 웹 개발 및 배포
    • Spring Boot Font 배포 에러
    • Spring AOP
      • Spring AOP로 모든 Request 로그 남기기
    • Spring Cache
    • Spring Cloud
      • Consul로 spring 설정 관리하기
    • Spring Test
      • Spring Test DirtiesContext
      • Spring Test MockBean, SpyBean
      • Spring Test Dynamic @Scheduled
    • Spring JDBC
    • Spring Validation
    • Spring Transaction Management
      • Spring with JTA 삽질
    • Spring에서 효율적으로 Static resource 관리하기
    • Zuul을 사용해서 Spring Reverse proxy 만들기
    • Spring Security
    • 스프링 어노테이션이 안 먹힐 때 의심해볼만한 것
    • Spring Data
    • Spring Webflux
      • Tobi 강연
  • 코드 리팩토링
    • 한번에 하나씩
  • 지속적 통합 (CI)
    • Jenkins pipeline 삽질기
  • Log Aggregator 정리
    • Flume 테스트
    • Fluentd 테스트
  • Web Socket 정리
  • Akka
    • Actor 모델
    • Supervision
  • IE 8 대응 정리
  • 함수형 프로그래밍
    • 모나드
  • Netty
    • Netty 기본 예제
    • Netty 주요 특징
    • Netty 부트스트랩
    • Netty 채널 파이프라인, 코덱
    • Netty 이벤트 모델
    • Netty 바이트 버퍼
  • 스칼라 관련 정리
    • Maven으로 컴파일하기
    • Scala def 괄호 여부의 차이
    • 스칼라 function, method 차이점
    • ScalaTest와 Spring 연동하기
    • Programming in Scala
  • J2S 컨퍼런스
  • Android
    • 테스트
    • NDK
  • DDOS
  • HTTP
  • HttpClient
  • Container
    • Image 개요
    • cri-o
    • kata containers
    • Open Container Initiative Image
    • Buildkit
  • Github pages
  • Static Website
  • Webhook
  • Service Discovery Tools
    • Etcd
    • Eureka
    • Consul
      • ACL
    • 비교
  • React
    • JSX
    • React Element
    • Components, Props
    • State, Lifecycle
    • Handling Event
    • Flux
  • Vagrant
    • SSH 접속
  • Linux
    • Systemd
    • Alternatives
  • Messaging protocols
    • XMPP
    • AMQP
  • Windows
    • Windows10 내장 우분투에 ssh 클라이언트로 접속하기
    • Windows10 Hyper-V와 Virtual Box가 충돌을 일으켰을 때
    • Hyper-V 기반 docker에서 Shared Drives 설정 실패할 때
    • 윈도우 개발환경 설정
    • Docker desktop 없이 docker 환경 세팅하기
    • UWP 앱을 항상 관리자권한으로 실행하는 바로가기 만들기
  • Spring camp 2017
    • Project Reactive
    • 이벤트 소싱
    • CQRS
  • Spring webflux
  • 리액티브 프로그래밍
  • Linux Settings
    • 홈서버 백업 및 복구기
    • 홈서버 트러블슈팅
  • Kubernetes
    • k3s 설치 및 삽질
    • pod resources
    • Argo workflow
    • 트러블 슈팅
      • Kubernetes namespace의 phase가 Terminating에서 멈춰있을 때
    • 쿠버네티스 마스터
    • Knative
    • Knative Pipeline
    • Aggrerated API server
    • Accessing the API
      • Authenticating
  • Sonarqube
  • HTTP/2
  • Go
    • Go Module
    • Go dependency injection
    • Go Error handling
    • Go in Action
      • 3장 패키지
      • 4장 배열, 슬라이스, 맵
      • 5장 GO의 타입 시스템
      • 6장 동시성
      • 7장 동시성 패턴
      • 8장 표준 라이브러리
      • 9장 테스트와 벤치마킹
    • Go Channel 사용법
  • Cloud Native
Powered by GitBook
On this page
  • Lambda Translation
  • 내부 순서
  • 변환 방법
  • Desugaring
  • 왜 final 변수만?
  • 참고
  1. Java 관련 정리

Java8 Lambda expression

Lambda Translation

이펙티브 자바에서 '익명 클래스를 사용하면 메소드가 호출되어 실행될 때마다 익명 클래스의 새로운 인스턴스가 생성된다. 따라서 만일 이 메소드가 반복해서 실행된다면, private static final 필드에 함수 객체 참조를 저장하고 재사용하는 것을 고려해야 한다.' 라는 항목을 보게 되어 갑자기 불안해졌다. 내 프로젝트에는 SomeCollection.forEach(Lambda expression) 이 잔뜩 있고, Lambda는 익명 클래스의 sugar syntax로 실제 실행 시엔 자동으로 적절한 Functional Interface의 구현체로 치환된다고 알고 있었는데, 그럼 Lambda도 같은 문제점이 존재하는게 아닌가 싶었기 때문이다.

뭐, 결론부터 내리자면 걱정할 필요는 없었다. forEach는 하나의 callback 객체를 가지고 반복문으로 동작하기 때문이다. 처음부터 불필요한 걱정이긴 했지만 덕분에 Lambda에 대해서 좀 더 찾아볼 수 있는 기회였다.

내부 순서

  1. 람다식이 컴파일된 결과인 invokedynamic instruction 호출됨

  2. LambdaMethodFactory.metafactory()로 capture argument 및 필요 정보들을 전달하여 CallSite 인스턴스 생성

  3. CallSite가 가지고 있는 MethodHandle의 invoke()를 호출하여 Functional Interface 생성

변환 방법

  • Lambda expression의 body를 클래스의 새로운 static method로 변환

    • capture 된 변수들은 모두 이 메소드의 argument

  • Functional Interface 중 하나를 구현하여 내부 클래스를 만들고 앞에서 변환한 static method를 연결

    • 만약에 stateful lambda라면 새로운 인스턴스를 생성

    • stateless lambda면 최초 호출에만 인스턴스를 생성하고 캐싱

Desugaring

Stateless

Lambda의 argument와 동일하게 argument를 갖는 static method 생성

Stateful

Lambda의 argument에 capture 될 변수들까지 추가하여 argument로 갖는 static method 생성. Functional Interface 인스턴스를 생성할 때 capture 된 변수들을 각각 argument로 넘겨주게 함

Stateful - instance member

위와 기본적으론 동일하나 Functional Interface 인스턴스를 생성할 때 capture 변수 그 자체가 아니라 클래스 인스턴스를 통째로 argument로 넘기게 함

왜 final 변수만?

We only allow capture of (effectively) final variables. So we can freely copy variables at point of capture

『From Lambdas to Bytecode』. Brian Goetz, Java Language Architect

참고

Previous9장 - ExceptionNextJDBC

Last updated 7 years ago

https://slipp.net/wiki/pages/viewpage.action?pageId=19530334
http://wiki.jvmlangsummit.com/images/1/1e/2011\_Goetz\_Lambda.pdf