developer tip

제네릭과 함께 Collections.emptySet ()을 사용하면 할당에서 작동하지만 메서드 매개 변수로는 작동하지 않는 이유는 무엇입니까?

copycodes 2021. 1. 10. 17:28
반응형

제네릭과 함께 Collections.emptySet ()을 사용하면 할당에서 작동하지만 메서드 매개 변수로는 작동하지 않는 이유는 무엇입니까?


따라서 다음과 같은 생성자가있는 클래스가 있습니다.

public FilterList(Set<Integer> labels) {
    ...
}

FilterList빈 세트 로 새 개체를 만들고 싶습니다 . Joshua Bloch의 저서 Effective Java에서 조언에 따라 빈 집합에 대한 새 개체를 만들고 싶지 않습니다. Collections.emptySet()대신 사용하겠습니다 .

FilterList emptyList = new FilterList(Collections.emptySet());

이것은 나에게 오류가 발생 java.util.Set<java.lang.Object>하여 java.util.Set<java.lang.Integer>. 좋아, 이건 어때?

FilterList emptyList = new FilterList((Set<Integer>)Collections.emptySet());

이것은 또한 나에게 오류를 준다! 좋아, 이건 어때?

Set<Integer> empty = Collections.emptySet();
FilterList emptyList = new FilterList(empty);

이봐, 작동한다! 그런데 왜? 결국 Java에는 유형 추론이 없기 때문에 .NET Set<Integer> foo = new TreeSet()대신 수행하면 확인되지 않은 변환 경고가 표시됩니다 Set<Integer> foo = new TreeSet<Integer>(). 그러나 Set<Integer> empty = Collections.emptySet();경고도없이 작동합니다. 왜 그런 겁니까?


짧은 대답은-이것이 Java의 제네릭 시스템에서 유형 추론의 한계입니다. 구체적인 변수에 대해서는 제네릭 유형을 추론 할 수 있지만 메서드 매개 변수에 대해서는 추론 할 수 없습니다.

나는 이것이 소유하는 객체의 런타임 클래스에 따라 메서드가 동적으로 디스패치되기 때문 이라고 생각 하므로 컴파일 타임에 ( 모든 일반 정보가 해결 될 때 ) 메서드 매개 변수의 클래스가 무엇인지 실제로 알 수 없으므로 추론 할 수 없습니다. 변수 선언은 훌륭하고 일정하므로 가능합니다.

다른 사람이 더 자세한 정보 및 / 또는 멋진 링크를 제공 할 수 있습니다. :-)

어쨌든 다음과 같이 일반 호출에 대해 명시 적으로 유형 매개 변수를 항상 지정할 수 있습니다.

Collections.<Integer>emptySet();

또는 한 번에 여러 매개 변수, 예를 들어

Collections.<String, Boolean>emptyMap(); // Returns a Map<String, Boolean>

추론이 시작되지 않는 경우 캐스팅하는 것보다 약간 더 깔끔해 보입니다.


시험

FilterList emptyList = new FilterList(Collections.<Integer>emptySet());

추론이 충분하지 않거나 하위 유형을 사용하도록 허용하는 경우이를 포함하는 메소드에 대해 유형 매개 변수를 강제 할 수 있습니다. 예를 들면 :

// forces use of ArrayList as parameter instead of the infered List
List<String> l = someObject.<ArrayList<String> methodThatTakesTypeParamForReturnType();

다음을 수행하려고합니다.

FilterList emptyList = new FilterList(java.util.Collections.<Integer>emptySet());

이는 emptySet메소드에 일반 매개 변수가 Integer기본값 대신 명시 적으로 지정되어야 함을 알려줍니다 Object. 그리고 예, 구문은 완전히 펑키하고 직관적이지 않습니다. :)


Java에는 유형 추론이 있지만 매우 제한적입니다. 작동 방식과 제한 사항을 정확히 아는 데 관심이 있다면 정말 좋은 읽기입니다.

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#Type%2BArgument%2BInference

참조 URL : https://stackoverflow.com/questions/3061837/why-does-using-collections-emptyset-with-generics-work-in-assignment-but-not-a

반응형