java) 익명구현객체 내에서 this 사용시 일반식과 람다식의 차이점이 뭔가요?
조회수 805회
일반식
commentEdit.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(commentEdit.getText().toString().length() == 0) {
if (listener != null && keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
listener.onDeleteKeyPressed(CommentModel.this);
return true;
}
}
return false;
}
});
람다식
commentEdit.setOnKeyListener((v, keyCode, event) -> {
if(commentEdit.getText().toString().length() == 0) {
if (listener != null && keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
listener.onDeleteKeyPressed(this); // 람다식 사용하면 그냥 this만 써도됨
return true;
}
}
return false;
});
첫번째 일반식의 익명구현객체 작성에서
listener.onDeleteKeyPressed(CommentModel.this);
지금은 CommentModel.this
라고 작성되어있지만 this
라고 작성하면 사진과 같은
오류를 띄웁니다.
보시다시피 제공되는 타입(익명구현객체 타입을 작성하므로)은 OnKeyListener
이고 onDeleteKeyPressed()
의 요구되는 타입은 CommentModel
타입입니다.
그래서 Comment
를 명시하고 this
를 사용해야 되더군요..
그런데 이 익명구현객체를 람다식으로 바꿔주면 this
만으로 해결이 되던데요..
이유가 뭔가요..?
1 답변
-
첫번째 일반식의 this 는 익명 이너 클래스안에 써있기 때문에 해당 익명 이너 클래스를 나타냅니다.
listener.onDeleteKeyPressed 의 인자로 CommentModel 이 전달되는걸 의도하시고 this 를 사용 하셨지만 View.OnKeyListener 가 들어갔기에 사진과 같은 오류를 띄우는 것입니다. 그래서 명시적으로 CommentModel.this 로 써주어야 합니다.
두번째 람다식의 this 는 람다식 안에서 써있기 떄문에 자신을 감싸고 있는 클래스를 나타냅니다.
그래서 listener.onDeleteKeyPressed 의 인자로 this 를 사용하시고 CommentModel 이 잘 전달되었기 때문에 문제가 없는것입니다.
해당 사항에 대한것은 오라클 공식 문서에서 확인할 수 있습니다. 15.27.2
Unlike code appearing in anonymous class declarations, the meaning of names and the this and super keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).
- 아..일반식으로 썼을때는 익명객체 안에서 this를 사용했기떄문에 onKeyListener 객체를 나타내서 에러를 냈던것이었군요.. 그런데 선생님, 그 두번째 람다식 안에서 this 를 사용한경우 자신을 감싸고 있는 클래스를 나타낸다고 하셨는데, 여기서 감싸고 있는 클래스가 이 코드들이 작성된 클래스(파일)을 말씀하시는거죠?, 즉 setOnKeyListener을 호출하는 commentEdit(EditText입니다)가 아니라, 이 코드가 작성된 클래스 자체를 가르키는거죠? codeslave 2021.3.8 23:43
- 감싸고 있는 클래스라고 하는것은 클래스가 선언되었다는 것을 말합니다. A.java 파일에 A 클래스가 있고, 람다식을 사용했다면 this 는 A 클래스를 의미하는것일거고, A 클래스 안에 B 클래스가 있고 거기서 람다식이 사용되었다면 람다식에서 this 는 B 를 의미할 것입니다. commentEdit 은 클래스가 사용되고 있는거지 선언된게 아니라서 해당사항이 안됩니다. 김은기 2021.3.9 11:21
- 아..이해가 가는것같습니다..commentEdit은 클래스 선언이아니라 단순 클래스 사용이라 this가 이걸 가르키는게 아니군요.. 그 선언된 클래스? 자체를 말하는것이네요.. codeslave 2021.3.10 00:12
댓글 입력