-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[item42] 람다에서의 this 키워드는 바깥 인스턴스를 가르키는 이유 #65
Comments
람다에서 this 키워드가 바깥 인스턴스를 가르키는 이유는 자바 스펙을 참고해보면 아래와 같아요
람다식에서 자신에 자신을 참조할 필요가 있는 일은 흔치 않은 일이다 (재귀적으로 자신을 호출하거나 다른 메소드를 호출하는 것) |
저도 람다가 어떤 메커니즘으로 동작하는지 모르지만 ㅠ public class Test {
private final int value = 100;
public LambdaTest test = new LambdaTest() {
final int value = 200;
@Override
public String getValue() {
return "value는? " + this.value;
}
};
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.test.getValue());
}
} 람다 public class Test2 {
private final int value = 100;
public LambdaTest test = () -> {
final int value = 200;
return "value는? " + this.value;
};
public static void main(String[] args) {
Test2 test = new Test2();
System.out.println(test.test.getValue());
}
} 최대한 변수 등을 동일하게 해서 바이트 코드를 비교해봤을때 익명 클래스와 람다는 다르게 해석되는거 같습니다. |
근본적인 원인
객체 내부로 값을복사이 문제를 해결하기위해 자바는 메서드의 매개변수, 지역변수를 멤버메서드 내부에서 생성한 객체가 사용할경우 이때, 변수에 final키워드가 붙거나 사실상 final(effectively final)인 성격을 가져야 한다는 제약이 있습니다 https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html 언급 제약이 있는 이유이 제약이 있는이유는 객체는 heap에있어 스레드간 공유가 가능한데, 지역변수는 stack에있어 스레드간 공유가 불가능하여. 결론자바는 이를 해결하기위해 heap영역에 존재하는 객체가 stack 영역의 변수를 안전하게 사용할수있도록 값 복사를 합니다. 영준님 코드 람다표현식에선 Test의 멤버변수 value를 복사한값을 참조하는것 같습니다 익명 객체는 만들때마다 별도의 객체를 계속 생성하지만, 람다는 별도의 객체를 생성하거나 별도의 클래스를 생성하지않고 새로운 메서드를 static으로 생성해 메서드를 실행시킵니다. 익명클래스와 람다의 스콥이 다를수밖에 없습니다 변수 캡처, effectively final 관련 자료 |
#61 (comment)
람다도 익명 객체인 것 같은데 this 키워드가 바깥 인스턴스를 가르키는지 이해가 안되네요ㅠㅠ
혹시 힌트가 있을까 하고 컴파일된 클래스 파일을 열어봤는데 궁금증 해결이 안됐습니다..
The text was updated successfully, but these errors were encountered: