Java의 일반 와일드 카드에 대한 몇 가지 질문이 있습니다.
-
List<? extends T>
과 의 차이점은 무엇입니까List<? super T>
? -
제한 와일드 카드 란 무엇이며 제한되지 않은 와일드 카드 란 무엇입니까?
답변
첫 번째 질문에서 <? extends T>
및 <? super T>
경계 와일드 카드의 예입니다. 제한되지 않은 와일드 카드는 다음과 같 <?>
으며 기본적으로 의미 <? extends Object>
합니다. 느슨하게 제네릭이 모든 유형이 될 수 있음을 의미합니다. 경계 와일드 카드 ( <? extends T>
또는 <? super T>
) 그 어느한다는 것을 말하며 종류에 제한을 둔다 연장 특정 유형 ( <? extends T>
상한로 알려져있다), 또는 특정 유형 (의 조상이어야 <? super T>
하한이라고 함) .
Java Tutorials에는 Wildcards 및 More Fun with Wildcards 기사에서 제네릭에 대한 꽤 좋은 설명이 있습니다.
답변
클래스 계층 구조 A가있는 경우 B는 A의 하위 클래스이고 C와 D는 모두 아래와 같이 B의 하위 클래스입니다.
class A {}
class B extends A {}
class C extends B {}
class D extends B {}
그때
List<? extends A> la;
la = new ArrayList<B>();
la = new ArrayList<C>();
la = new ArrayList<D>();
List<? super B> lb;
lb = new ArrayList<A>(); //fine
lb = new ArrayList<C>(); //will not compile
public void someMethod(List<? extends B> lb) {
B b = lb.get(0); // is fine
lb.add(new C()); //will not compile as we do not know the type of the list, only that it is bounded above by B
}
public void otherMethod(List<? super B> lb) {
B b = lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A
lb.add(new B()); // is fine, as we know that it will be a super type of A
}
제한된 와일드 카드는 ? extends B
B가 어떤 유형 인 경우 와 같습니다 . 즉, 유형을 알 수 없지만 “바운드”를 배치 할 수 있습니다. 이 경우 B의 하위 클래스 인 일부 클래스에 의해 제한됩니다.
답변
조쉬 블로흐도 사용하는 경우의 좋은 설명이 있습니다 super
및 extends
이의 비디오 이야기 IO 구글 그가 언급 생산자 extends
소비자super
니모닉.
프레젠테이션 슬라이드에서 :
대량 메서드를 추가하려는 경우
Stack<E>
void pushAll(Collection<? extends E> src);
– src는 E 생산자입니다.
void popAll(Collection<? super E> dst);
– dst는 E 소비자입니다.
답변
유형 매개 변수에 전달할 수있는 유형의 종류를 제한하려는 경우가있을 수 있습니다. 예를 들어 숫자에 대해 작동하는 메서드는 Number 또는 해당 하위 클래스의 인스턴스 만 허용하려고 할 수 있습니다. 이것이 경계 유형 매개 변수의 용도입니다.
Collection<? extends MyObject>
즉, MyObject와 IS-A 관계를 가진 모든 개체 (즉, myObject의 유형 인 모든 개체 또는 MyObject의 모든 하위 클래스의 개체라고 말할 수 있음) 또는 MyObject 클래스의 개체를 허용 할 수 있습니다.
예를 들면 :
class MyObject {}
class YourObject extends MyObject{}
class OurObject extends MyObject{}
그때,
Collection<? extends MyObject> myObject;
MyObject 또는 MyObject의 자식 (즉, OurObject, YourObject 또는 MyObject 유형의 모든 개체, MyObject의 수퍼 클래스 개체 제외) 만 허용합니다.
답변
일반적으로
구조에 형식 유형의 요소가 포함되어있는 경우 구조에서 요소를
? extends E
가져올 수 있지만 구조에 요소를 넣을 수는 없습니다.
List<Integer> ints = new ArrayList<Integer>();
ints.add(1);
ints.add(2);
List<? extends Number> nums = ints;
nums.add(3.14); // compile-time error
assert ints.toString().equals("[1, 2, 3.14]");
구조에 요소를 넣으려면라는 다른 종류의 와일드 카드가 필요합니다 Wildcards with super
.
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
답변
컬렉션에서 작동하는 메서드를보다 재사용 가능하게 만들기 위해 일반 와일드 카드가 생성됩니다.
예를 들어 메소드에 매개 변수가있는 경우이 메소드 List<A>
에만 제공 할 수 있습니다 List<A>
. 어떤 상황에서는이 방법의 기능이 낭비입니다.
- 이 메서드가에서만 객체를 읽는다면이 메서드
List<A>
에 제공List<A-sub>
할 수 있어야합니다 . (A-sub가 A이기 때문에) - 이 메서드가 객체를에 삽입하기 만하면이 메서드
List<A>
에 제공List<A-super>
할 수 있습니다 . (A는 A 슈퍼이기 때문에)