람다
사용 법
(인자 리스트) -> {바디}
인자 리스트
- 인자가 없을 때: ()
- 인자가 한 개일 때: (one) 또는 one
- 인자가 여러 개 일 때: (one, two)
- 인자의 타입은 생략 가능, 컴파일러가 추론(infer)하지만 명시할 수도 있다. (Integer one, Integer two)
바디
- 화상표 오른쪽에 함수 본문을 정의한다.
- 여러 줄인 경우에 { }를 사용해서 묶는다.
- 한 줄인 경우에 생략 가능, return도 생략 가능.
변수 캡처 (Variable Capture)
Effective Final
우선적으로 로컬 클래스, 익명 클래스, 람다를 정의해보자
로컬 클래스
/*로컬 클래스*/
class LocalClass {
void printBaseNumber() {
System.out.println("Local Class : "+baseNumber);
}
}
익명 클래스
/*익명 클래스*/
Consumer<Integer> integerConsumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println("Anonymous Class : "+baseNumber);
}
};
람다
/*람다*/
IntConsumer printint = (i) -> {
System.out.println("Lamda : "+ (i+ baseNumber));
};
위의 세 가지 예시 보드 baseNumber라는 LocalVariable을 참조하고 있다.
만약 해당 LocalVariable에 final 키워드를 생략하면 오류가 날까?
자바 8 이전 버전에서는 final 키워드가 필수적이었다. 하지만 자바 8 이후의 버전에서는 사실상의 final인 경우 (변경을 못하는 경우) 생략이 가능하다.
이때 사실상의 final을 effective final이라 명칭 한다.
쉐도 윙
쉐도잉이란 같은 네이밍의 다수의 로컬 변수가 있다고 가정할 때 여러 개의 가장 안쪽의 로컬 변수가 우선적으로 참조된다는 것이다. 다른 말로 외부의 로컬 변수의 값은 무시된다는 의미이다.
아래 그림을 풀어서 설명하자만 메서드 내부에 로컬 클래스, 익명 클래스, 람다가 있는데 로컬 클래스와 익명 클래스는 쉐도잉의 대상이고 람다는 쉐도잉의 대상이 아니다.
왜일까?
이유는 Scope의 차이이다.
아래는 익명 클래스와 로컬 클래스를 예시로 들었다. 같은 baseNumber의 이름을 가질지라도 각자의 변수의 Scope이 다르기 때문에 익명 클래스 혹은 로컬 클래스에서 똑같은 이름의 변수의 값을 재정의 하면 기존에 외부에 있던 로컬 변수의 값은 무시된다. (쉐도잉 된다.)
하나 람다는 기존의 로컬 변수와 같은 Scope이기 때문에 쉐도잉이 일어나지 않는다.
(같은 Scope에서는 같은 이름의 변수를 정의할 수 없기 때문에)
Code Link
https://github.com/mike6321/PURE_JAVA/tree/master/java8to11
'Java > Java8' 카테고리의 다른 글
(JAVA8) Optional은 언제 사용해야할까? (0) | 2021.03.17 |
---|---|
(JAVA8) 람다 표현식과 메서드 래퍼런스 (2) (0) | 2020.07.23 |
(JAVA8) 함수형 인터페이스와 람다 표현식 (2) (0) | 2020.07.07 |
(JAVA8) 함수형 인터페이스와 람다 표현식 (1) (0) | 2020.07.07 |
(JAVA8) 스트림의 활용 (2) (0) | 2020.01.19 |