반응형
람다 문법
- (인자 리스트) -> {바디}
인자 리스트
- 인자가 없을 때: ()
- 인자가 한개일 때: (one) 또는 one
- 인자가 여러개 일 때: (one, two)
- 인자의 타입은 생략 가능, 컴파일러가 추론(infer)하지만 명시할 수도 있다.
- (Integer one, Integer two)
바디
- 화살표 오른쪽에 함수 본문을 정의한다.
- 여러 줄인 경우에 { }를 사용해서 묶는다.
- 한 줄인 경우에 생략 가능, return도 생략 가능.
변수 캡처 (Variable Capture)
- 로컬 변수 캡처
- final이거나 effective final 인 경우에만 참조할 수 있다.
- 그렇지 않을 경우 concurrency 문제가 생길 수 있어서 컴파일러가 방지한다.
- effective final
- 이것도 역시 자바 8부터 지원하는 기능으로 “사실상" final인 변수.
- final 키워드 사용하지 않은 변수를 익명 클래스 구현체 또는 람다에서 참조할 수 있다.
- Nested 클래스(로컬, 익명 클래스, 등) 구현체와 달리 ‘쉐도윙’하지 않는다.
- Shadowing : 낮은 스코프에서 동일한 이름의 로컬 변수가 있으면 상위 스코프의 변수가 해당 스코프에서 가려지는 현상. 해당 스코프에서는 동일한 이름의 로컬 변수의 값이 우선적으로 사용된다.
- 익명 클래스는 새로 스코프을 만들지만, 람다는 람다를 감싸고 있는 스코프과 같다. 따라서 쉐도윙이 발생할 수 없다.
변수 캡처 예제
public class Foo {
public static void main(String[] args) {
Foo foo = new Foo();
foo.run();
}
private void run() {
/*
자바 8 이전에는 로컬, 익명 클래스에서 외부 변수를 참조하기 위해서는 final 키워드를 선언해주어야 한다.
final int baseNumber = 10;
*/
int baseNumber = 10; //자바 8 부터 사실상 상수(effectively final)도 로컬 변수 캡처 가능
//로컬 클래스
class LocalClass {
int baseNumber = 20; //쉐도윙 발생. 외부의 10의 값이 가려지고 로컬 변수인 20으로 적용된다.
void printBaseNumber() {
System.out.println(baseNumber);
}
}
//익명 클래스
Consumer<Integer> integerConsumer = new Consumer<Integer>() {
@Override
public void accept(Integer baseNumber) {
//쉐도윙 발생. 외부의 10의 값이 가려지고 매개 변수인 baseNumber으로 적용된다.
System.out.println(baseNumber);
}
};
//람다
IntConsumer printInt = (i) -> {
//int baseNumber = 40; 쉐도윙 불가능. 에러 발생
System.out.println(i + baseNumber);
};
new LocalClass().printBaseNumber(); //로컬 클래스
integerConsumer.accept(5); //익명 클래스
printInt.accept(30); //람다
}
}
[참고자료]
반응형
'Java > 기본' 카테고리의 다른 글
자바 인터페이스(Java Interface) 변화 - 1 (기본 메소드, 스태틱 메소드) (0) | 2021.06.22 |
---|---|
자바 람다(Java Lambda) - 4 (메소드 레퍼런스) (0) | 2021.06.20 |
자바 람다(Java Lambda) - 2 (자바 함수형 인터페이스) (0) | 2021.06.16 |
자바 람다(Java Lambda) - 1 (함수형 인터페이스, 람다 표현식) (0) | 2021.06.15 |
자바 애노테이션 프로세서(Java Annotation Processor) (0) | 2021.06.03 |