<aside> 📖 이 장의 내용

</aside>


9.1 가독성과 유연성을 개선하는 리팩터링

람다 표현식은 익명 클래스보다 코드를 좀 더 간결하게 만든다. 람다, 메서드 참조, 스트림 등의 기능을 이용해서 더 가독성이 좋고 유연한 코드로 리팩터링하는 방법을 살펴보자.

9.1.1 코드 가독성 개선

가독성을 개선한다는 것은 구현한 코드를 다른 사람이 쉽게 이해하고 유지보수할 수 있게 만드는 것을 의미한다. 코드 가독성을 높이려면 코드의 문서화를 잘 하고, 표준 코딩 규칙을 준수해야한다.

9.1.2 익명 클래스를 람다 표현식으로 리팩터링하기

왜 익명 클래스를 람다 표현식으로 리팩터링 하는 것일까 ? → 익명클래스는 코드를 장황하게 만들고 쉽게 에러를 일으키기 때문이다. 즉, 익명클래스를 람다 표현식으로 변환하면 간결하고 가독성 좋은 코드를 구현할 수 있다.

하지만 모든 익명 클래스를 람다 표현식으로 변환할 수 있는 것은 아니다. 아래 주의점을 주의 깊게 보자.

익명클래스를 람다표현식으로 변환할 때 주의점

  1. 익명클래스에서 this는 익명클래스 자신을 가리키지만 람다에서 this는 람다를 감싸는 클래스를 가리킨다. (즉, 익명 클래스에서 사용한 this와 super는 람다 표현식에서 다른 의미를 갖는다)

  2. 익명클래스는 감싸고있는 클래스의 변수를 가릴 수 있지만, 람다 표현식으로는 가릴 수 없다.

  3. 익명클래스를 람다 표현식으로 바꾸면 콘텍스트 오버로딩에 따른 모호함이 초래될 수 있다. → 익명 클래스는 인스턴스화할 때 명시적으로 형식이 정해지는 반면 람다의 형식은 콘텍스트에 따라 달라지기 때문이다. 이 말도 어려울 수 있다. 다시 말해, 람다 표현식이 어떤 함수형 인터페이스를 구현하는지에 따라 다른 결과를 가져올 수 있기 때문에 '콘텍스트 오버로딩'에 따른 모호함이 발생할 수 있다는 것이다.

interface Task {
public void execute();
}

public static void doSomething(Runnable r) { r.run(); }
public static void doSomething(Task a) { r.excute(); }

//익명클래스로 전달 가능
doSomethig(new Task() {
public void execute() {
System.out.println("Danger danger!!");
}
});

//Runnable과 Task 모두 대상 형식이 가능하므로 모호함 발생
doSomething(() -> System.out.println("Danger danger!!"));

//명시적 형변환을 사용해서 모호함을 제거할 수 있음
doSomething((Task)() -> System.out.println("Danger danger!!"));

9.1.3 람다 표현식을 메서드 참조로 리팩터링하기

메서드 참조를 사용하면 메서드명으로 코드의 의도를 명확히 알릴 수 있다.