[Java] Lambda - This Reference

반응형

이번 글에서는 lambda의 this refernece에 대해 알아보도록 하겠습니다.

1. This Reference

this reference란 java에서 current object를 reference하는 방법으로 사용되는 keyword를 의미합니다.

1-1) implements class

아마, 이 글을 보고 계신분들도.. 이미 this refence를 사용해본 경험이 있을 겁니다. 😅

예를 들어 다음과 같이

public class ThisReferenceExample {
    public static void main(String[] args) {
        ThisReferenceExample thisReferenceExample = new ThisReferenceExample();
        thisReferenceExample.doProcess(10, new Consumer<Integer>(){
            @Override
            public void accept(Integer i) {
                System.out.println(i);
                System.out.println(this);
            }
        });
    }

    private void doProcess(int i, Consumer<Integer> consumer) {
        consumer.accept(i);
    }
}

Consumer를 구현한 익명 클래스의 accept 메서드에서 this reference를 사용할 수 있습니다.

그렇다면 위의 this가 reference하는 object는 무엇일까요?? 😎

위의 익명 클래스 내부 'this'는 해당 익명 클래스의 instance를 지칭합니다.

출력해보면 위와 같이 this가 ThisReferenceExample의 instance 인 것을 확인할 수 있습니다.

확실히 하기 위해 익명클래스 내부 toString 메서드를 아래와 같이 재정의하고

thisReferenceExample.doProcess(10, new Consumer<Integer>(){
        @Override
        public void accept(Integer i) {
            System.out.println(i);
            System.out.println(this);
        }

        @Override
        public String toString() {
            return "This is the anonymous inner class";
        }
});

출력해보면 다음과 같이 익명 클래스 인스턴스의 toString 메서드를 정상적으로 호출하는 것을 확인할 수 있습니다.

1-2) lambda

lambda에서도 this reference를 사용할 수 있을까요? 😅

"네, 사용할 수 있습니다."

하지만 lambda의 this reference는 익명 클래스의 this reference와는 다른 object를 reference 합니다.

예를 들어 아래와 같이 작성하면

public class ThisReferenceExample {
    public static void main(String[] args) {
        ThisReferenceExample thisReferenceExample = new ThisReferenceExample();
        thisReferenceExample.doProcess(10, i -> System.out.println(this));
    }

    private void doProcess(int i, Consumer<Integer> consumer) {
        consumer.accept(i);
    }
}

다음과 같이 에러가 발생합니다.

이게 무슨 의미일까요..?

사실, 이전 글에서 설명드렸듯이.. lambda 로 정의한 '기능'은 instance를 생성하지 않습니다.

또한 lambda는 해당 lambda 식이 작성된 class의 instance를 reference 합니다. 즉, Consumer가 아닌 ThisReferenceExample object를 reference 합니다.

결론적으로 위의 예제에서 this reference에 에러가 발생한 이유는, lambda 식이 선언된 메서드가 static 메서드이기 때문입니다.

static 메서드에 선언된 메서드는 ThisReferenceExample 인스턴스 없이도 호출될 수 있기 때문에, ThisReferenceExample object를 reference하는 this reference에 에러가 발생하게 된 것 입니다.

따라서 다음과 같이 코드를 변경하면 에러가 없어지게 됩니다.

public class ThisReferenceExample {
    public static void main(String[] args) {
        ThisReferenceExample thisReferenceExample = new ThisReferenceExample();
        thisReferenceExample.execute();
    }

    private void execute(){
        doProcess(10, i -> System.out.println(this));
    }

    private void doProcess(int i, Consumer<Integer> consumer) {
        consumer.accept(i);
    }

    @Override
    public String toString() {
        return "This is ThisReferenceExample class";
    }
}

this reference를 사용하는 lambda식이 instance method에 작성되었으므로, 이제 위의 this는 ThisReferenceExample instance를 reference 할 수 있게 되었습니다.

출력결과는 위와 같습니다. 😎


추천서적

 

이것이 자바다:신용권의 Java 프로그래밍 정복

COUPANG

www.coupang.com

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음


반응형

'Java' 카테고리의 다른 글

[Java] Lambda - Foreach Iteration  (0) 2020.08.17
[Java] Lambda - Method Reference  (0) 2020.08.16
[Java] Lambda - Closure  (0) 2020.08.16
[Java] Lambda - Exception Handling  (0) 2020.08.16
[Java] Lambda - Functional Interface  (0) 2020.08.16

댓글

Designed by JB FACTORY