class JustSort {
public void sort(List<?> list) {
Collections.reverse(list);
}
}
class TestMain {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, -2, 6, -4, 0);
list = new ArrayList<>(list);
JustSort js = new JustSort();
Consumer<List<Integer>> c1 = e -> js.sort(e); // 인스턴스 생성에 같은 지역에 선언된 참조변수에 접근
Consumer<List<Integer>> c2=new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) {
js.sort(integers); // 인스턴스 생성에 같은 지역에 선언된 참조변수에 접근
}
};
c1.accept(list);
System.out.print(list);
}
}
람다식에서 참조하는 지역변수는 final로 선언되었거나 effectively final 변수여야 한다.
즉, 위의 람다식에서 쓰인 참조변수 js는 참조하는 인스턴스가 변경될 수 없다.
따라서 다음과 같은 코드가 작성 될 경우 컴파일 에러가 발생한다.
class JustSort {
public void sort(List<?> list) {
Collections.reverse(list);
}
}
class TestMain {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, -2, 6, -4, 0);
list = new ArrayList<>(list);
JustSort js = new JustSort();
js=new JustSort(); // final 또는 effectively final 성격이 깨져서 컴파일 에러가 발생한다.
Consumer<List<Integer>> c1 = e -> js.sort(e);
Consumer<List<Integer>> c2=new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) {
js.sort(integers);
}
};
c1.accept(list);
System.out.print(list);
}
}
만약 위 코드가 컴파일 에러를 발생하지 않고 final 또는 effectively final 변수가 아니여도 허용을 해서 js가 참조하는 인스턴스를 변경할 수 있다면 js.sort 메소드의 결과는 예측할 수가 없게 된다.
참고
인스턴스의 생성은 힙 영역에 할당이 이뤄지고 지역 변수는 스택 영역에 할당이 이뤄진다.
'Programming > JAVA' 카테고리의 다른 글
Optional Map (0) | 2020.12.12 |
---|---|
Lambda Expression (0) | 2020.12.10 |
Nested Class, Inner Class (0) | 2020.12.08 |
댓글