Java

[Java]익명 내부 클래스와 람다식의 차이점

DevStory 2022. 6. 21.

이번 포스팅은 익명 내부 클래스(Anonymous Inner Class)와 람다식(Lambda Expression)의 차이점에 대해 소개합니다. 


익명 내부 클래스

  • 익명 내부 클래스는 이름이 없는 클래스입니다.
  • 특정 작업을 위해 메서드를 오버로드하거나 기능을 확장해야 하는 경우 상속 없이 인스턴스화 할 수 있습니다.
  • 익명 내부 클래스는 일반적으로 추상/구현 클래스 또는 인터페이스를 구현합니다.

익명 내부 클래스 예제 1. 정렬

다음 예제는 String 타입의 ArrayList를 정렬하기 위해 Comparator 인터페이스를 익명 내부 클래스를 사용하여 인스턴스화 합니다.

public class Main {
  public static void main(String args[]) {
    // Comparator<String> 인터페이스를 구현 클래스 없이 인스턴스화 합니다.
    Comparator<String> comparator = new Comparator<String>() {
      @Override
      public int compare(String str1, String str2) {
        return str1.compareTo(str2);
      }
    };

    // String 타입의 ArrayList 생성
    ArrayList<String> strArrayList = new ArrayList<>();
    strArrayList.add("가방");
    strArrayList.add("다방");
    strArrayList.add("나방");
    strArrayList.add("가나");
    System.out.println("정렬 전: " + strArrayList);

    Collections.sort(strArrayList, comparator);
    System.out.println("정렬 후: " + strArrayList);
  }
}

실행 결과

정렬 전: [가방, 다방, 나방, 가나]
정렬 후: [가나, 가방, 나방, 다방]

익명 내부 클래스 예제 2. 스레드

다음 예제는 Runnable 인터페이스가 run() 메서드 내부에 새로운 기능을 추가하기 위해 인스턴스화 되었음을 보여줍니다.

public class Main {
  public static void main(String args[]) {
    // Runnable 인터페이스를 익명 내부 클래스로 인스턴스화 합니다.
    Runnable run = new Runnable() {
      @Override
      public void run() {
        System.out.println("run() 메서드 호출!");
      }
    };

    Thread thread = new Thread(run);
    thread.start();
  }
}

실행 결과

run() 메서드 호출!

람다 표현식

  • 람다 표현식은 기본적으로 함수형 인터페이스의 인스턴스를 표현합니다.(하나의 추상 메서드를 가지는 인터페이스를 함수형 인터페이스라고 말합니다.)
  • Java 8 버전부터 사용 가능합니다.
  • 익명 내부 클래스보다 코드가 짧습니다.

람다 표현식 예제 1. 정렬

다음 예제는 String 타입의 ArrayList를 정렬하기 위해 Comparator 인터페이스를 람다 표현식으로 구현합니다.

public class Main {
  public static void main(String args[]) {
    // Comparator 인터페이스의 compare 메서드를 람다식으로 구현합니다.
    Comparator<String> comparator = (str1, str2) -> str1.compareTo(str2);

    // String 타입의 ArrayList 생성
    ArrayList<String> strArrayList = new ArrayList<>();
    strArrayList.add("가방");
    strArrayList.add("다방");
    strArrayList.add("나방");
    strArrayList.add("가나");
    System.out.println("정렬 전: " + strArrayList);

    Collections.sort(strArrayList, comparator);
    System.out.println("정렬 후: " + strArrayList);
  }
}

실행 결과

정렬 전: [가방, 다방, 나방, 가나]
정렬 후: [가나, 가방, 나방, 다방]

람다 표현식 예제 2. 스레드

다음 예제는 Runnable 인터페이스를 람다식으로 구현합니다.

public class Main {
  public static void main(String args[]) {
    // Runnable 인터페이스를 람다식으로 구현합니다.
    Runnable run = () -> System.out.println("run() 메서드 호출!");

    Thread thread = new Thread(run);
    thread.start();
  }
}

실행 결과

run() 메서드 호출!

비교

익명 내부 클래스 람다 표현식
이름이 없는 클래스입니다. 이름이 없는 메서드입니다.
추상 및 구체 클래스를 확장할 수 있습니다. 추상 및 구체 클래스를 확장할 수 없습니다.
여러 추상 메서드를 포함하는 인터페이스를 구현할 수 있습니다. 단일 추상 메서드를 퐇마하는 인터페이스를 구현할 수 있습니다.
익명 내부 클래스 내부에서 인스턴스 변수를 선언할 수 있습니다. 인스턴스 변수를 선언할 수 없습니다.
익명 내부 클래스를 인스턴스화 할 수 있습니다. 람다 표현식을 인스턴스화 할 수 없습니다.
익명 내부 클래스 내부의 this 키워드는 현재 익명 내부 클래스 객체를 참조합니다. 람다 표현식 내부의 this 키워드는 현재 외부 클래스 객체를 나타냅니다.
반응형

댓글