티스토리 뷰

자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 두 번째는 람다 표현식이다.

람다 표현식의 기본 형태는 다음과 같다.

🐻 (인자 리스트) → (바디)

앞에서 봤던 함수형 인터페이스 예시 코드에도 람다 표현식이 등장했다.

public class UseDoSomething {
    public static void main(String[] args) {
        DoSomething doSomething = () ->
                System.out.println("eric test");
        doSomething.print();
    }
}

인자 리스트

  • 인자가 없을 때 : () ⇒ 대개 Supplier에 해당한다.
  • 인자가 하나 일 때 : (value) 또는 value
  • 인자가 여러 개 일 때 : (value1, value2)
  • 컴파일러가 추론이 가능하므로 인자의 타입은 생략 가능하다. (물론, 명시도 가능하다.)

바디

  • 화살표 오른쪽에 함수 본문을 정의한다.
  • 여러 줄인 경우에는 { }를 사용해서 묶고 한 줄인 경우에는 return과 함께 생략이 가능하다.

람다는 익명 클래스와 로컬 클래스와는 달리 쉐도잉을 하지 않는다.

쉐도잉이 무엇인지 살펴보기 전에 람다와 익명 클래스, 로컬 클래스의 예시 코드를 살펴보자.

public class App {
		public static void main(String[] args) {
        App app = new App();
        app.run();
    }

    private void run() {
        final int baseNumber = 10;

        // 로컬 클래스
        class LocalClass {
            void printBaseNumber() {
                System.out.println(baseNumber);
            }
        }

        // 익명 클래스
        Consumer<Integer> integerConsumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(baseNumber);
            }
        };

        // 람다
        IntConsumer printInt = (i) -> System.out.println(i + baseNumber);

        printInt.accept(10);
    }
}

자바 8 이전에는 람다에서 외부 변수(baseNumber)를 사용하려면 final 키워드를 명시해줘야 했다.

하지만 자바 8부터는 effective final 이라는 기능이 생겼다.

final을 붙이지 않아도 그 변수가 사실상 final이라면 사용이 가능했다.

사실상 final?

사실상 final이라는 것은 외부 변수(baseNumber)가 변경되지 않으면 자바 내부에서 사실상 final이라고 인식한다.

⇒ effective final 하다라고 인식한다는 의미.

쉐도잉

이제 쉐도잉을 알아보자.

쉐도잉이란 scope을 만든다는 걸 의미한다.

다음 코드를 살펴보자.

public class App {
    int scopeTest = 10;
    
    public static void main(String[] args) {
        App app = new App();
        app.scopeTestMethod();
    }
    void scopeTestMethod() {
        int scopeTest = 20;
        System.out.println(scopeTest);
    }
}

// 출력 결과
20

위처럼 맨 위 코드에서 scopeTest를 10으로 선언했어도 scopeTestMethod 메서드에서 scopeTest를 재선언을 하는 행위를 쉐도잉이라고 한다.

메서드 내 scope을 새로 만들어 메서드내에서는 scopeTest를 20으로 사용하게 된다.

위같은 행위를 로컬 클래스와 익명 클래스에서는 가능하지만 람다에서는 불가능하다.

local class vs. inner class

위에서 등장한 지역 클래스(local class)와 inner class의 차이점이 궁금해져서 찾아보았다.

간단하게 설명하자면 다음과 같다.

  • inner class는 클래스 내부의 클래스를 선언하는 것
  • local class는 메서드 내의 클래스를 선언하는 것

effective java 아이템 [42] 에서는 위에서 언급한 익명 클래스보다는 람다를 사용하기를 권고한다.

익명 클래스 방식은 코드가 너무 길기 때문에 자바는 함수형 프로그래밍에 적합하지 않았다.

자바 8에 와서 추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정받아 특별한 대우를 받게 되었다.

이게 바로 이전 장에서 설명한 함수형 인터페이스이다.

지금은 함수형 인터페이스를 부르는 이 인터페이스들의 인스턴스를 람다식을 사용해 만들 수 있게 되었다.

람다는 함수 익명 클래스와 개념은 비슷하지만 코드는 훨씬 간결하다.

 

람다와 익명 클래스 차이는 다음에 자세히 다뤄보려고 한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함