시나리오는 다음과 같습니다.
public static <T> List<T> isTriggeredByBlackList(Map<String, T> params, Class<T> clz) {
System.out.println(clz.getName());
return null;
}
내가 원하는 것은 String
또는 List<String>
이 방법 을 전달 하는 것입니다.
에 관해서는 String
잘 작동합니다.
Map<String, String> map1 = new HashMap<String, String>();
map1.put("11", "22");
isTriggeredByBlackList(map1, String.class);
하지만을 전달하려고하면 List<String>
잘못되었습니다.
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> l = new ArrayList<String>();
l.add("11");
l.add("22");
map.put("1", l);
isTriggeredByBlackList(map, List.class); //compile error!
아래와 같이 컴파일 오류 :
The method isTriggeredByBlackList(Map<String,T>, Class<T>) in the type CommonTest is not applicable for the arguments (Map<String,List<String>>, Class<List>)
내가 필요한 것은 유형과 유형 모두에 적합한 하나의 메소드 를 작성하는 것입니다 .String
List<String>
누구든지 나를 도울 수 있습니까? 감사합니다!
방법의 서명을 변경하십시오.
public static <T> List<T> isTriggeredByBlackList(Map<String, ? extends T> params, Class<T> clz)
왜 이것이 작동합니까?
표현식 ? extends T
은 하위 유형 T
(물론 T
그 자체) 인 모든 유형 이 허용 된다는 것을 의미합니다 .
그래서 메소드 isTriggeredByBlackList
가 다음과 같이 호출 될 때 :
isTriggeredByBlackList(map, List.class);
... T
(raw) List
유형 으로 지정 되므로 첫 번째 매개 변수는 여야합니다. Map<String, any-type-that-extends-raw-List>
이는 (raw)의 하위 유형 Map<String, List<String>>
이기 때문에 true입니다 .List<String>
List
그러나 목록이 (원시) 목록의 하위 유형 인 이유는 무엇입니까?
다형성이 예상대로 작동하지 않기 때문에 제네릭은 까다 롭습니다. A List<String>
is-NOT-a List<Object>
, String
확장 하지만 Object
! 따라서 이것은 작동하지 않습니다.
List<Object> objList = new ArrayList<String>(); // compile error
(참고 : 이것이 불가능하다는 것은 좋지만 다른 이야기입니다)
그러나이 List<String>
A-IS (원료) List
(그것은 이다-A List<?>
). 그래서 이것은 작동합니다.
List rawList = new ArrayList<String>(); // just compiler warning
List<?> unknownList = new ArrayList<String>();
그 이유는 원시 유형이 여전히 이전 버전과 호환되도록 지원되기 때문입니다. 그렇지 않으면 제네릭을 지원하지 않는 오래된 코드는 요즘 사용할 수 없습니다. 따라서 구체적인 매개 변수화 된 유형 (예 :)의 인스턴스는 ArrayList<String>
원시 유형 (예 :) ArrayList
또는 수퍼 유형 (예 :) 의 참조에 할당 될 수 있습니다 List
!
왜 우리는 다음과 같은 것을 통과 할 수 List<String>.class
없습니까?
매개 변수화 된 유형에는 정확한 런타임 유형 표현이 없기 때문입니다!
구체적인 매개 변수화 된 유형에 대한 클래스 리터럴이없는 이유는 무엇입니까?
그러나 나는 List<List<String>>
반환 값 을 얻고 싶다 !
이것은 문제 없습니다! 할당의 왼쪽을 a로 정의 List<List<String>>
하면 나머지는 java가 처리합니다.
List<List<String>> l = isTriggeredByBlackList(map, List.class);
그러나! 메서드 선언을 약간 수정 한 경우에만 작동합니다.
public static <T> List<T> isTriggeredByBlackList(
Map<String, ? extends T> params, Class<? super T> clz)
(그렇지 않으면 원시 List.class
를 두 번째 인수로 전달할 수 없습니다 ).
이 모든 수정 및 조정이 합리적이라면 방법이 수행해야하는 작업에 따라 달라집니다! 읽기만 params
하나요? 제네릭 유형 인수를 어떻게 사용합니까? 여기서 제네릭을 사용하면 어떤 이점이 있습니까? 기타
Btw .:로 시작하는 메서드 is...
는 boolean
값을 반환해야 합니다. 방법의 이름을 바꾸는 것을 고려하십시오! 당신의 메서드의 반환 형식입니다 : BTW 2 List<T>
, 그래서 경우에 당신이 지정하고 T
을 할 List
, 당신은 얻을 것이다 List<List>
. 이것은 의도 된 것입니까?
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다