Collections.emptyList ()는 List <Object>?를 반환합니다.


269

일반 유형 매개 변수를 유추하는 Java 규칙을 탐색하는 데 문제가 있습니다. 선택적 목록 매개 변수가있는 다음 클래스를 고려하십시오.

import java.util.Collections;
import java.util.List;

public class Person {
  private String name;
  private List<String> nicknames;

  public Person(String name) {
    this(name,Collections.emptyList());
  }

  public Person(String name,List<String> nicknames) {
    this.name = name;
    this.nicknames = nicknames;
  }
}

내 Java 컴파일러는 다음 오류를 제공합니다.

Person.java:9: The constructor Person(String, List<Object>) is undefined

그러나 Collections.emptyList()type <T> List<T>이 아닌을 반환합니다 List<Object>. 캐스트를 추가해도 도움이되지 않습니다

public Person(String name) {
  this(name,(List<String>)Collections.emptyList());
}

수확량

Person.java:9: inconvertible types

EMPTY_LIST대신에 사용emptyList()

public Person(String name) {
  this(name,Collections.EMPTY_LIST);
}

수확량

Person.java:9: warning: [unchecked] unchecked conversion

다음과 같이 변경하면 오류가 사라집니다.

public Person(String name) {
  this.name = name;
  this.nicknames = Collections.emptyList();
}

누구든지 내가 여기에서 실행중인 유형 검사 규칙과 그 문제를 해결하는 가장 좋은 방법을 설명 할 수 있습니까? 이 예제에서 최종 코드 예제는 만족 스럽지만 클래스가 클수록 코드를 복제하지 않고이 "선택적 매개 변수"패턴에 따라 메소드를 작성할 수 있기를 원합니다.

추가 크레딧 : EMPTY_LIST대신에 사용하는 것이 언제 적절한 emptyList()가요?


1
모든 Java Generics 관련 질문에 대해 필립와 들러 Maurice Naftalin의 " Java Generics and Collections "를 적극 권장 합니다.
Julien Chastang

답변:


447

발생하는 문제는 메소드 emptyList()가을 반환 하더라도 List<T>유형을 제공하지 않았으므로 기본값은으로 반환된다는 것 List<Object>입니다. type 매개 변수를 제공하고 다음과 같이 코드가 예상대로 작동하도록 할 수 있습니다.

public Person(String name) {
  this(name,Collections.<String>emptyList());
}

이제 직접 할당을 수행 할 때 컴파일러가 일반 유형 매개 변수를 알아낼 수 있습니다. 이것을 타입 추론이라고합니다. 예를 들어, 이렇게 한 경우 :

public Person(String name) {
  List<String> emptyList = Collections.emptyList();
  this(name, emptyList);
}

그런 다음 emptyList()호출은을 올바르게 반환합니다 List<String>.


12
알았다. ML 세계에서 왔을 때, Java가 올바른 유형을 유추 할 수 없다는 것은 이상합니다. 형식 매개 변수의 유형과 emptyList의 반환 유형은 명확하게 알 수 없습니다. 그러나 형식 유추자는 "아기 단계"만 취할 수 있다고 생각합니다.
Chris Conway

5
간단한 경우에는 컴파일러가이 경우 누락 된 형식 매개 변수를 유추하는 것이 가능할 수 있지만 위험 할 수 있습니다. 다른 버전의 메소드가 여러 버전으로 존재하면 잘못된 버전을 호출하게됩니다. 그리고 두 번째 것은 아직 존재하지 않을 수도 있습니다 ...
Bill Michell

13
"Collections. <String> emptyList ()"표기법은 정말 이상하지만 의미가 있습니다. Enum <E >>보다 쉽게 ​​Enum <E >>를 확장합니다. :)
Thiago Chaves

12
Java 8에서는 더 이상 유형 매개 변수를 제공 할 필요가 없습니다 (일반적인 유형이 모호하지 않는 한).
Vitalii Fedorenko

9
두 번째 스 니펫은 형식 유추를 훌륭하게 보여 주지만 물론 컴파일되지는 않습니다. 에 대한 호출 this은 생성자에서 첫 번째 명령문이어야합니다.
Arjan

99

사용하고 싶은 것 :

Collections.<String>emptyList();

emptyList가 무엇인지 소스를 보면 실제로는

return (List<T>)EMPTY_LIST;

26

emptyList 메소드에는 다음과 같은 서명이 있습니다.

public static final <T> List<T> emptyList()

즉, <T>이 결과에 할당되는 변수의 형태에서 일반적인 파라미터 T 값을 유추하는 단어 목록 수단 전에. 따라서이 경우 :

List<String> stringList = Collections.emptyList();

그런 다음 반환 값은 type 변수에 의해 명시 적으로 참조 List<String>되므로 컴파일러가이를 알아낼 수 있습니다. 이 경우 :

setList(Collections.emptyList());

컴파일러가 제네릭 형식을 파악하는 데 사용할 명시적인 반환 변수가 없으므로 기본값은 Object입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.