it-source

Collections는 ListCollections.emptyList()를 합니다.Collections는 ListCollections.emptyList()를 합니다.Collections는 ListCollections.emptyList()를 합니다.무슨 일입니까?무슨 일입니까?무슨 일입니까?범용 유형 매개 변..

criticalcode 2022. 11. 1. 00:00
반응형

Collections는 ListCollections.emptyList()를 합니다.무슨 일입니까?

범용 유형 매개 변수를 추론하는 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()returns 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()?

당신이 겪고 있는 문제는 그 방법이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>.

사용하고 싶은 항목:

Collections.<String>emptyList();

어떤 emptyList의 소스를 보면 실제로는 이 소스에 의해

return (List<T>)EMPTY_LIST;

emptyList 메서드의 시그니처는 다음과 같습니다.

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

그거<T>List라는 단어 앞에 있는 것은 결과가 할당된 변수 유형에서 일반 매개변수 T의 값을 유추하는 것을 의미합니다.이 경우:

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

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

setList(Collections.emptyList());

컴파일러가 범용 타입을 알아내기 위해 사용하는 명시적인 반환 변수는 없습니다.기본값은 다음과 같습니다.Object.

Java 8에서는 이러한 종류의 코드가 예상대로 컴파일되어 type 파라미터가 컴파일러에 의해 추론됩니다.

public Person(String name) {
    this(name, Collections.emptyList()); // Inferred to List<String> in Java 8
}

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

Java 8의 새로운 기능은 표현식의 대상 유형이 하위 표현식의 유형 매개 변수를 추론하는 데 사용된다는 것입니다.Java 8 이전에는 형식 매개 변수 추론에 사용되는 메서드에만 할당 및 인수를 지정했습니다.

이 경우 생성자의 매개 변수 유형이 다음 대상 유형이 됩니다.Collections.emptyList()파라미터 유형과 일치하도록 반환값 유형이 선택됩니다.

이 메커니즘은 주로 람다 식을 컴파일하기 위해 Java 8에서 추가되었지만 일반적으로 유형 추론을 개선합니다.

Java는 매 릴리즈마다 적절한 힌들리-밀러 타입의 추론에 가까워지고 있습니다.

언급URL : https://stackoverflow.com/questions/306713/collections-emptylist-returns-a-listobject

반응형