변수 유효 범위
종종 람다 표현식에서 해당 표현식을 감싸고 있는 메서드나 클래스에 있는 변수에 접근하고 싶은 경우가 있다.
예를 들어 repeatMessage(String text, int count) 같은 메소드가 있고
repeatMessage("Hello", 1000);를 통해 호출하였다고 가정하여 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public static void repeatMessage(String text, int count) { Runnable r = () -> { for (int i = 0; i < count; i ++) { System.out.println(text); Thread.yield(); } }; new Thread(r).start(); } public static void main(String args[]) { repeatMessage("wedul", 10); } | cs |
text, count는 repeatMessage 메소드 내부에 있는 변수 이다.
해당 메소드를 호출하였을 때. repeatMessage 메소드가 종료되고 나서 람다식이 실행 될 수도 있다.
그런데 어떻게 해당 매개변수가 남아 있을 수 있을까?
해당 코드의 람다식에는 파라미터도 아니고 코드 내부에도 정의되지 않은 자유 변수 두개(text, count)가 존재한다.
람다식은 이 변수의 값을 사용하기 위해서 이들 값을 따로 저장하는 Capture 라는 동작을 수행한다.
람다 표현식은 단일 메서드를 갖춘 객체로 변환하고, 자유 변수들의 값을 해당 객체의 인스턴스 변수로 복사한다.
해당 방식처럼 자유변수들의 값을 포함하는 코드 블록의 기술 용어를 Closure라고 한다.
1 2 3 4 5 6 7 8 9 10 11 | Public static void repeatMessage(String text, int count) { Runnable r = () -> { While( count > 0 ) { count--; // 캡쳐 변수는 변경되는 값을 포함할 수 없다. System.out.println(text); Thread.yield(); } }; New Thread(r).start(); } | cs |
기존에는 저렇게 사용하기 위해서는 넘어온 데이터를 변경하기 위해서
넘어온 데이터가 final로 선언되어 있어야 했다.
하지만 클로저 기능을 통해 값이 캡처가 되고 변경이 되지 않으면서 final을 구태여 붙히지 않아도 된다.
람다 표현식의 중첩 블록 내의 유효범위
람다 표현식과 그를 포함하고 있는 블록과 동일한 유효범위를 가진다.
위에 예제에서 보면 람다 표현식인 Runnable 상위에 str문자열 객체와 동일한 변수에 접근하여 사용하는 것을 알 수 있다.
그렇기 때문에 그 하단처럼 같은 이름의 변수를 같이 사용하면 안된다.
람다 표현식의 this 키워드
람다표현식에서 this 키워드는 결국 람다를 생성하는 객체의 this 키워드를 사용하는 것과 같다.
'JAVA > Java 8' 카테고리의 다른 글
Java8 인터페이스의 정적 메소드 (0) | 2018.05.30 |
---|---|
Java8 인터페이스 default Method (디폴트 메소드) (0) | 2018.05.30 |
Java8 생성자 레퍼런스 (0) | 2018.05.30 |
Java8 메서드 레퍼런스 (0) | 2018.05.30 |
Java8 기초 설명 (0) | 2018.05.30 |