java8에서 동작(함수)를 파라미터화 하기 위해서 클래스의 선언과 인스턴스화를 동시에 수행할 수 있도록 익명 클래스라는 기법을 사용하였다.
익명 클래스를 전달 할 시 코드의 장황함을 해결하기 위해서 람다 표현식이 활용 된다.
위와 같이 람다식을 인자로 넘기는 코드가 가능한 이유는 OnclickListener에 추상 메소드가 단 하나만 있기 때문이다.
이렇게 하나의 추상 메소드를 가진 인터페이스를 함수형 인터페이스(functional interface) 또는 SAM인터페이스-single abstract method라고 한다.
코틀린은 함수형 인터페이스를 인자로 취하는 자바 메소드를 호출할 때 람다를 넘길 수 있게 해준다.
익명클래스 전달코드를 간소화 하기 위해 람다식을 이용하지만, 내부적으로 람다와 익명클래스 사이에는 차이가 있다.
익명클래스를 이용할 시에는 매번 새로운 익명 클래스의 인스턴스가 생성 되지만,
람다는 단 하나의 인스턴스만 만들고 그 무명 객체를 메소드를 호출할 때마다 반복 사용한다.
매번 같은 인스턴스를 사용한다면, 란다가 주변 영역의 변수는 어떻게 포획(capture)하는걸까? 이런 경우 컴파일러는 매번 주변 영역의 변수를 포획한 새로운 인스턴스를 생성해 준다.
SAM생성자를 통한 람다 반환
컴파일러가 자동으로 람다를 함수형 인터페이스의 익명 클래스로 바꾸지 못하는 경우 SAM생성자를 사용해야 하는데,
바로 함수형 인터페이스의 인스턴스를 반환하는 메소드가 있을 경우 그렇다.
자바는 생성자 없이 되던데..
람다안의 this 람다 안에서 this는 그 람다를 둘러싼 클래스의 인스턴스를 가리킨다.
만약 이벤트 리스너가 이벤트를 처리하다가 자기 자신의 리스너 등록을 해제해야 한다면, (람다 안에서 익명 클래스의 인스턴스 자체를 호출해야 한다면) 람다를 사용 할 수 없다.
이런 경우 람다 대신 익명 객체를 사용해서 리스너를 구현해야 한다. 익명 객체 안에서는 this가 그 익명 객체 인스턴스 자신을 가리킨다.