제네릭과 함께 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
'developer tip' 카테고리의 다른 글
InetAddress.getLocalHost () 실행 속도가 느림 (30 초 이상) (0) | 2021.01.10 |
---|---|
iOS 11에서 Xcode 8 사용 (0) | 2021.01.10 |
IIS URL 재 작성 및 Web.config (0) | 2021.01.10 |
MVC 3 Razor에서 활성 페이지 링크를 얻는 더 나은 방법 (0) | 2021.01.10 |
다음 json 문자열을 Java 객체로 변환하는 방법은 무엇입니까? (0) | 2021.01.10 |