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만으로 해결이 되던데요..

이유가 뭔가요..?

  • new View.OnKeyListener 처럼 View 클래스에 바인딩 된 이벤트 리스너 인스턴스를 생성해서 그런 것 같은데요. commentEdit:CommentModel -> View 관계라면 "View."을 빼면 되지 않을까요? doodoji 2021.3.8 13:28

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

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)