기본 콘텐츠로 건너뛰기

방송대 방통대 Java프로그래밍 6강 - 제네릭과 람다식 - 요약 노트 시험족보 예상문제 - 올에이클래스

Java프로그래밍 6강 - 제네릭과 람다식

Java프로그래밍 6강 - 제네릭과 람다식

타입을 매개변수로 전달하는 제네릭을 통해 코드의 재사용성과 타입 안전성을 높이는 방법을 학습한다. 이어서 제네릭 클래스·인터페이스·메소드와 타입 제한을 살펴보고, 함수형 인터페이스의 구현을 간결하게 표현하는 람다식의 문법과 활용 방법을 정리한다.

1. 제네릭의 의미와 장점

타입을 매개변수로 다루는 기법

제네릭(generic)은 클래스, 인터페이스, 메소드를 정의할 때 구체적인 자료형을 바로 정하지 않고 타입 매개변수를 선언하는 기법이다. 실제로 사용할 때 필요한 참조형을 지정하므로 하나의 정의를 여러 자료형에 재사용할 수 있다. 타입 매개변수를 가진 클래스와 인터페이스를 제네릭 타입이라고 하며, 메소드 자체에 타입 매개변수를 선언하면 제네릭 메소드가 된다.

제네릭이 제공하는 이점

  • 여러 자료형에 공통으로 동작하는 일반화된 클래스나 메소드를 정의할 수 있다.
  • 사용 가능한 자료형을 한정하여 컴파일 시점에 정확한 타입 검사를 수행할 수 있다.
  • 잘못된 자료형 사용을 실행 전에 찾아 오류 수정이 쉬워진다.
  • 객체를 꺼낼 때 반복적으로 사용하던 캐스트 연산자를 줄일 수 있다.
  • 같은 로직을 자료형마다 다시 작성하지 않아 코드 재사용성이 높아진다.

제네릭의 핵심은 하나의 코드를 여러 참조형에 재사용하면서 자료형 오류를 컴파일 시점에 발견하는 것이다.

2. 제네릭 사용과 컬렉션 예제

타입을 지정하지 않은 List

ArrayList<E>List<E> 인터페이스를 구현한 제네릭 클래스이다. 타입을 지정하지 않은 목록은 원소를 사실상 Object로 다루므로 값을 꺼낸 후 원하는 자료형으로 명시적 형변환을 해야 한다.

List list1 = new ArrayList();
list1.add("hello");
String s1 = (String) list1.get(0);

타입을 지정한 List

목록을 만들 때 String을 타입 인자로 지정하면 컴파일러가 저장 가능한 원소와 반환 자료형을 알 수 있다. 다른 자료형의 저장은 컴파일 단계에서 막고, 꺼낸 값은 별도의 캐스트 없이 String으로 사용할 수 있다.

List<String> list2 = new ArrayList<String>();
list2.add("hello");
String s2 = list2.get(0);

타입 인자는 String, Integer 같은 참조형으로 지정한다. 기본 자료형을 직접 타입 인자로 사용할 수는 없다.

3. 제네릭 클래스의 정의

기본 문법

제네릭 클래스는 클래스 이름의 오른쪽에 각괄호를 쓰고 타입 매개변수를 선언한다. 여러 타입 매개변수는 쉼표로 구분한다. 이름에는 관례적으로 원소를 뜻하는 E, 키를 뜻하는 K, 값을 뜻하는 V, 숫자를 뜻하는 N, 일반 타입을 뜻하는 T 등을 사용한다.

class 클래스이름<T1, T2> {
    // 필드와 메소드 정의
}

타입 매개변수를 사용할 수 있는 위치

타입 매개변수는 인스턴스 필드의 자료형, 메소드 반환형, 메소드 매개변수의 자료형 등으로 사용할 수 있다. 클래스를 실제로 사용할 때 구체적인 타입 인자를 지정하면 클래스 내부의 T가 그 자료형으로 해석된다.

class Data<T> {
    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
}

Data<String>에서는 set()의 인자와 get()의 반환형이 String이 되고, Data<Integer>에서는 모두 Integer가 된다. 같은 클래스 정의가 서로 다른 자료형에 맞게 재사용되는 것이다.

4. 제네릭 클래스가 필요한 이유와 raw 타입

Object 기반 클래스의 문제

필드의 자료형을 Object로 선언하면 어떤 객체든 저장할 수 있지만, 컴파일러가 실제 저장된 자료형을 보장하지 못한다. 다음처럼 Integer를 저장한 뒤 String으로 형변환해도 컴파일은 통과할 수 있으며, 실행할 때 형변환 오류가 발생한다.

Data data = new Data();
data.set(Integer.valueOf(20));
String text = (String) data.get(); // 실행 오류

제네릭 타입 검사

Data<String>처럼 자료형을 한정하면 Integer를 전달하는 문장 자체가 컴파일 오류가 된다. 반면 get()의 반환형은 이미 String으로 정해져 있으므로 캐스트가 필요 없다.

Data<String> data = new Data<>();
data.set(Integer.valueOf(20)); // 컴파일 오류
String text = data.get();

생성자 호출의 타입 인자는 앞의 변수 선언으로 충분히 추론할 수 있으면 다이아몬드 연산자 <>만 남겨 간결하게 작성할 수 있다.

raw 타입

raw 타입은 제네릭 타입을 타입 매개변수 없이 일반 타입처럼 사용하는 형태이다. 예를 들어 Data data = new Data("hello");에서 DataData<T>의 raw 타입이다. 이 경우 타입 매개변수는 Object처럼 처리되어 제네릭의 컴파일 시점 타입 안전성을 잃는다.

raw 타입은 제네릭 문법을 쓰지 않은 기존 코드와의 호환에는 쓰일 수 있지만, 새 코드에서는 구체적인 타입 인자를 지정하여 컴파일러의 검사를 받는 것이 바람직하다.

5. 제네릭 인터페이스와 구현 클래스

제네릭 인터페이스

인터페이스도 하나 이상의 타입 매개변수를 가질 수 있다. 다음 Pair<K, V>는 키와 값의 자료형을 각각 매개변수로 선언한다.

interface Pair<K, V> {
    K getKey();
    V getValue();
}

제네릭 구현 클래스

구현 클래스 자체도 타입 매개변수를 유지하려면 인터페이스의 타입 인자를 같은 매개변수로 전달한다. 이렇게 정의한 OrderedPair<K, V>는 다양한 키와 값 조합에 재사용할 수 있다.

class OrderedPair<K, V> implements Pair<K, V> {
    private K key;
    private V value;

    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() { return key; }
    public V getValue() { return value; }
}
Pair<String, Integer> p1 =
    new OrderedPair<>("Even", 8);
Pair<String, String> p2 =
    new OrderedPair<>("hello", "java");

타입을 고정하는 일반 클래스

일반 클래스가 제네릭 인터페이스를 구현하면서 타입 인자를 구체적으로 고정할 수도 있다. MyPair implements Pair<String, Integer>라고 쓰면 getKey()String, getValue()Integer를 반환하도록 구현해야 한다.

구현 클래스가 타입 매개변수를 계속 받으면 제네릭 클래스이고, 인터페이스의 타입 인자를 구체적으로 지정하면 그 구현 클래스는 일반 클래스가 될 수 있다.

6. 제네릭 메소드

메소드 자체의 타입 매개변수

제네릭 메소드는 자료형을 매개변수로 가지는 메소드이다. 메소드 선언에서 반환형 앞의 각괄호 안에 타입 매개변수를 표시한다. 이 타입은 반환형, 메소드 매개변수, 지역 변수의 자료형으로 사용할 수 있다.

public <T> void swap(T[] array, int i, int j) {
    T temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

swap()은 배열 원소의 구체적인 참조형과 관계없이 두 원소의 위치를 바꿀 수 있다. 클래스 전체를 제네릭으로 만들 필요 없이 특정 메소드만 여러 자료형에 공통으로 동작하게 할 때 유용하다.

인스턴스 메소드와 static 메소드

제네릭 메소드는 인스턴스 메소드와 static 메소드 모두로 정의할 수 있다. 여러 타입 매개변수가 필요하면 <K, V>처럼 쉼표로 구분한다.

class Util {
    public static <K, V> boolean compare(
            Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey())
            && p1.getValue().equals(p2.getValue());
    }
}

호출할 때 Util.<Integer, String>compare(p1, p2)처럼 타입을 명시할 수 있지만, 전달되는 인자에서 타입을 추론할 수 있으면 보통 생략한다.

제네릭 클래스의 타입 매개변수는 클래스 전체에 적용되고, 제네릭 메소드의 타입 매개변수는 해당 메소드 선언에 적용된다.

7. 타입 제한과 제네릭 타입의 형변환

상한 제한

제네릭 클래스·인터페이스·메소드가 받을 수 있는 자료형을 제한할 수 있다. <T extends Number>TNumber 또는 그 하위 클래스만 올 수 있다는 뜻이다. 따라서 IntegerDouble은 가능하지만 String은 사용할 수 없다.

class Data<T extends Number> {
    private T value;

    public Data(T value) {
        this.value = value;
    }

    public T get() { return value; }
}

Data<Integer> ok = new Data<>(20);
Data<String> error = new Data<>("Hello"); // 오류

타입 인자 사이의 관계

IntegerDouble은 모두 Number의 자식 클래스이다. 그러나 이 사실만으로 Data<Integer>Data<Number>의 하위 타입이 되는 것은 아니다. 따라서 다음 대입은 컴파일 오류이다.

Data<Number> data = new Data<Integer>(); // 오류

반면 제네릭 클래스 자체 사이에 실제 상속 관계가 있고 타입 인자도 같으면 대입할 수 있다.

class FormattedData<T> extends Data<T> { }

Data<Integer> data = new FormattedData<Integer>(); // 가능

타입 인자의 상속 관계와 제네릭 타입 자체의 상속 관계를 혼동하지 않는다. IntegerNumber의 하위 타입이어도 Data<Integer>Data<Number> 사이에는 자동 상속 관계가 생기지 않는다.

8. 제네릭 타입 사용 시 유의 사항

기본 자료형 사용 불가

타입 매개변수에는 참조형만 지정할 수 있으므로 Data<int>는 사용할 수 없다. 정수가 필요하다면 래퍼 클래스인 Integer를 사용한다.

타입 매개변수로 직접 객체 생성 불가

new T()처럼 타입 매개변수의 객체를 직접 생성할 수 없다. 컴파일 시점의 타입 소거와 생성자 정보의 불확실성 때문에 허용되지 않는다.

static 문맥에서 클래스 타입 매개변수 사용 불가

클래스의 타입 매개변수는 객체별로 정해지는 인스턴스 문맥에 속한다. 따라서 static T value처럼 정적 필드의 자료형으로 직접 사용할 수 없다. 필요한 경우 정적 메소드 자체에 별도의 타입 매개변수를 선언한다.

제네릭 배열의 제한

제네릭 타입을 원소로 하는 배열은 타입 안전성 문제 때문에 사용에 제약이 있다. 강의록에서는 Data<Integer>[] 형태를 오류 사례로 제시하며, 일반적으로 제네릭 타입의 배열을 직접 생성하지 않는다.

제약오류 예대안 또는 의미
기본 자료형 불가Data<int>Data<Integer> 사용
타입 객체 직접 생성 불가new T()외부에서 객체나 생성 정보를 전달
정적 필드에 클래스 T 사용 불가static T value인스턴스 필드 또는 별도 제네릭 메소드 사용
제네릭 배열 제약new Data<Integer>[10]컬렉션 등 타입 안전한 구조 활용

9. 람다식과 함수형 인터페이스

람다식의 의미

람다식(lambda expression)은 인터페이스를 구현하는 익명 클래스에서 객체를 생성하는 부분을 간결하게 표현한 것이다. 구현해야 할 추상 메소드가 하나뿐일 때 익명 구현 클래스의 반복적인 문법을 줄일 수 있다.

Runnable runnable = new Runnable() {
    public void run() {
        System.out.println("my thread");
    }
};

Runnable runnable2 =
    () -> System.out.println("my thread");

함수형 인터페이스와 타깃 타입

추상 메소드를 하나만 가진 인터페이스를 함수형 인터페이스라고 한다. 람다식은 독립적인 자료형이 아니라 대입되는 함수형 인터페이스를 타깃 타입으로 삼는다. 컴파일러는 타깃 타입의 추상 메소드 선언에서 매개변수 자료형과 반환형을 추론한다.

추상 메소드가 둘 이상인 인터페이스에는 하나의 람다식이 어느 메소드를 구현하는지 결정할 수 없으므로 사용할 수 없다. 람다식은 이름 없는 메소드 선언과 유사하지만, 실제로는 함수형 인터페이스의 구현 객체를 표현한다.

람다식의 전제는 타깃 타입이 추상 메소드 하나를 가진 함수형 인터페이스라는 점이다.

10. 람다식의 기본 문법과 축약

기본 형태

인터페이스변수 = (매개변수목록) -> { 실행문목록 };

람다식은 매개변수 목록, 화살표 ->, 메소드 몸체로 구성된다. 매개변수의 자료형은 타깃 타입의 추상 메소드에서 알 수 있으므로 생략할 수 있다.

매개변수 목록 단순화

  • 매개변수가 여러 개이면 괄호 안에 쉼표로 나열한다.
  • 자료형을 생략할 때는 일부만 생략하지 않고 전체 매개변수의 자료형을 함께 생략한다.
  • 매개변수가 하나이면 자료형과 괄호를 함께 생략해 변수 이름만 남길 수 있다.
  • 매개변수가 없으면 빈 괄호 ()를 사용한다.

메소드 몸체 단순화

  • 실행문이 하나이면 중괄호를 생략할 수 있다.
  • 몸체가 return문 하나뿐이면 return, 중괄호, 세미콜론을 함께 생략하고 수식만 적는다.
(int a, int b) -> { return a + b; }
(a, b) -> { return a + b; }
(a, b) -> a + b

(int value) -> { System.out.println(value); }
value -> System.out.println(value)

return이 남아 있는 상태에서 중괄호만 제거할 수는 없다. 표현식 몸체로 줄일 때는 return과 세미콜론도 함께 제거한다.

11. 람다식 사용 예

두 정수를 더하는 함수형 인터페이스

interface Addable {
    int add(int a, int b);
}

익명 구현 클래스는 클래스 선언과 메소드 재정의를 모두 작성해야 하지만, 람다식은 추상 메소드의 매개변수와 몸체만 남긴다. 아래 세 구현은 모두 두 수의 합을 반환한다.

Addable ad1 = new Addable() {
    public int add(int a, int b) {
        return a + b;
    }
};

Addable ad2 = (int a, int b) -> {
    return a + b;
};

Addable ad3 = (a, b) -> a + b;

void 메소드의 람다식

반환값이 없는 추상 메소드는 실행문을 몸체에 작성한다. 실행문이 하나라면 중괄호를 생략할 수 있고, 매개변수가 하나이면 괄호도 생략할 수 있다.

MyInterface1 f1 = (int a, int b) -> {
    System.out.println(a + b);
};

MyInterface1 f2 =
    (a, b) -> System.out.println(a + b);

MyInterface2 f3 =
    a -> System.out.println(a);

12. 표준 함수형 인터페이스와 람다 활용

java.util.function 패키지

Java는 java.util.function 패키지에서 자주 사용하는 표준 함수형 인터페이스를 제네릭 인터페이스로 제공한다. 필요한 함수 모양에 맞는 인터페이스를 선택하면 별도의 인터페이스를 매번 정의하지 않아도 된다.

인터페이스대표 추상 메소드의미
Consumer<T>void accept(T t)값을 받아 소비하고 결과를 반환하지 않음
Supplier<T>T get()매개변수 없이 값을 공급
Function<T, R>R apply(T t)입력값을 받아 다른 결과값으로 변환

스레드와 난수 예제

Thread thread = new Thread(
    () -> System.out.println("my thread")
);
thread.start();

Thread 생성자에 전달한 람다식은 Runnablerun()을 구현한다. 추상 메소드가 하나이므로 익명 클래스 없이 실행 내용을 전달할 수 있다.

Supplier<Integer> randomNumber = () -> {
    Integer number = (int) (Math.random() * 10);
    return number;
};

int value = randomNumber.get();
System.out.println(value);

Supplier<Integer>get()은 매개변수 없이 Integer를 반환한다. 람다식의 빈 괄호는 매개변수가 없음을 나타내며, 반환된 난수는 get()으로 얻는다.

람다식은 새로운 기능을 만드는 별개의 실행 체계가 아니라 함수형 인터페이스의 구현을 간결하게 전달하는 문법이다. 어떤 인터페이스가 타깃 타입인지와 그 추상 메소드의 매개변수·반환형을 먼저 확인해야 한다.

핵심 개념 정리

  • 제네릭은 클래스·인터페이스·메소드 정의에 타입 매개변수를 두고 실제 사용 시 참조형을 지정하는 기법이다.
  • 제네릭은 코드 재사용성을 높이고 자료형 오류를 컴파일 시점에 발견하며 불필요한 캐스트를 줄인다.
  • 제네릭 클래스의 타입 매개변수는 필드, 메소드 인자, 반환형 등에 사용할 수 있다.
  • 타입 매개변수는 참조형만 받을 수 있으며 여러 개이면 쉼표로 구분한다.
  • raw 타입은 타입 인자를 생략한 제네릭 타입으로, 값이 Object처럼 처리되어 타입 안전성을 잃는다.
  • 제네릭 인터페이스는 제네릭 클래스로 구현하거나 구체적인 타입을 고정한 일반 클래스로 구현할 수 있다.
  • 제네릭 메소드는 반환형 앞에 자체 타입 매개변수를 선언하며 인스턴스·정적 메소드 모두 가능하다.
  • <T extends Number>는 타입 인자를 Number와 그 하위 클래스로 제한한다.
  • IntegerNumber의 하위 타입이어도 Data<Integer>Data<Number>의 하위 타입이 아니다.
  • 기본 자료형, new T(), 클래스 타입 매개변수를 사용한 정적 필드, 제네릭 배열에는 사용 제약이 있다.
  • 람다식은 추상 메소드 하나를 가진 함수형 인터페이스의 구현 객체를 간결하게 표현한다.
  • 람다식의 자료형은 타깃 타입이며 컴파일러는 추상 메소드에서 매개변수 자료형과 반환형을 추론한다.
  • 람다식은 매개변수 자료형, 단일 매개변수의 괄호, 단일 실행문의 중괄호를 조건에 따라 생략할 수 있다.
  • 표현식 하나를 반환하면 return, 중괄호, 세미콜론을 함께 생략할 수 있다.
  • Consumer, Supplier, Functionjava.util.function의 대표적인 표준 함수형 인터페이스이다.

6강의 핵심은 제네릭으로 자료형을 매개변수화하여 안전한 재사용 코드를 만들고, 람다식으로 함수형 인터페이스의 단일 동작을 간결하게 전달하는 것이다. 두 문법 모두 컴파일러의 타입 검사와 추론을 적극적으로 활용한다.

예상문제 20선

1. 제네릭의 장점으로 옳지 않은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
제네릭은 자료형을 한정하여 잘못된 사용을 컴파일 시점에 발견한다. 오류를 실행 시점으로 미루는 것과 반대되는 목적을 가진다.

2. List<String>을 사용하는 효과로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
List<String>은 원소 자료형을 String으로 한정한다. 따라서 잘못된 저장을 막고 조회 결과의 캐스트도 필요 없게 한다.

3. 제네릭 클래스 정의에서 여러 타입 매개변수를 올바르게 선언한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
타입 매개변수는 클래스 이름 오른쪽의 각괄호 안에 쓰고, 여러 개는 쉼표로 구분한다.

4. Data<String> data = new Data<>();에서 <>의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
컴파일러가 변수 선언의 Data<String>에서 생성할 객체의 타입 인자를 추론하므로 생성자 쪽에는 <>만 쓸 수 있다.

5. raw 타입에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
raw 타입은 Data<T>를 단순히 Data로 사용하는 형태이다. 타입 안전성이 약해지고 조회 시 캐스트가 필요할 수 있다.

6. 제네릭 인터페이스 Pair<K,V>를 제네릭 구현 클래스로 올바르게 선언한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
구현 클래스가 타입 매개변수를 유지하려면 클래스 선언에도 <K,V>를 두고 인터페이스에 같은 타입을 전달한다.

7. 일반 클래스가 Pair의 키를 String, 값을 Integer로 고정하여 구현하는 선언은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
제네릭 인터페이스의 타입 인자를 구체적으로 지정하면 구현 클래스 자체는 별도의 타입 매개변수가 없는 일반 클래스가 될 수 있다.

8. 제네릭 메소드에서 타입 매개변수를 쓰는 위치로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
public <T> void swap(...)처럼 제네릭 메소드의 타입 매개변수는 반환형 앞에 선언한다.

9. 제네릭 메소드에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
제네릭 메소드는 인스턴스·정적 메소드 모두 가능하며, 전달되는 인자에서 자료형을 추론할 수 있으면 호출 시 타입 명시도 생략할 수 있다.

10. <T extends Number>의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
extends를 이용한 상한 제한이므로 Number, Integer, Double 등은 가능하고 String은 불가능하다.

11. 다음 중 컴파일 오류가 발생하는 대입은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
IntegerNumber의 하위 타입이어도 Data<Integer>Data<Number>의 하위 타입이 아니다.

12. 제네릭 타입 사용 시 올바른 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
타입 인자에는 참조형인 Integer를 사용할 수 있다. 기본형 int, new T(), 클래스 T를 사용한 정적 필드는 허용되지 않는다.

13. 람다식에 대한 설명으로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
람다식은 추상 메소드 하나를 가진 인터페이스의 구현 객체를 매개변수 목록, 화살표, 몸체로 간결하게 나타낸다.

14. 함수형 인터페이스의 조건은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
람다식이 구현할 동작을 하나로 결정할 수 있도록 함수형 인터페이스는 추상 메소드를 하나만 가진다.

15. 람다식의 타깃 타입이 하는 역할은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
컴파일러는 대입되는 함수형 인터페이스의 단일 추상 메소드에서 람다식의 매개변수와 결과 자료형을 추론한다.

16. Addable의 add(int a, int b)가 합을 반환할 때 가장 간결한 람다식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
반환할 표현식이 하나이면 return, 중괄호, 세미콜론을 함께 생략하여 (a, b) -> a + b로 쓸 수 있다.

17. 매개변수가 하나인 void 메소드를 출력문 하나로 구현할 때 가능한 람다식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
매개변수가 하나이면 자료형과 괄호를 생략할 수 있고, 실행문도 하나이면 중괄호를 생략할 수 있다.

18. 값을 매개변수 없이 공급하는 표준 함수형 인터페이스는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
Supplier<T>는 매개변수가 없는 T get() 메소드를 가지며 호출자에게 값을 공급한다.

19. Consumer<T>의 대표 추상 메소드와 기능의 연결로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
Consumer<T>는 값을 소비하는 역할이며 대표 메소드 accept()void를 반환한다.

20. Thread 생성자에 () -> System.out.println("my thread")를 전달할 수 있는 이유는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
Runnable은 단일 추상 메소드 run()을 가지므로 람다식의 타깃 타입이 될 수 있다. 빈 괄호는 매개변수가 없음을 나타낸다.

댓글