차이 와 자바에서 [중복]
이 질문에 이미 답변이 있습니다.
List<? super T>
과 의 차이점은 무엇입니까 List<? extends T>
?
내가 사용하는 데 사용 List<? extends T>
하지만, 내가 그것에 요소를 추가 할 수 없습니다 list.add(e)
(가) 반면, List<? super T>
않습니다.
extends
와일드 카드 선언은 List<? extends Number> foo3
다음 중 하나가 법적 할당임을 의미합니다.
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
읽기 -위의 가능한 할당이 주어지면 어떤 유형의 객체를 읽을 수 있습니까
List foo3
?- 또는의 하위 클래스
Number
를foo3
포함 하도록 할당 할 수있는 목록 중 하나를 읽을 수 있습니다 .Number
Number
- 을 가리킬 수
Integer
있기 때문에 읽을 수 없습니다 .foo3
List<Double>
- 을 가리킬 수
Double
있기 때문에 읽을 수 없습니다 .foo3
List<Integer>
- 또는의 하위 클래스
쓰기 감안할 때 당신이 추가 할 수있는 개체의 유형 가능한 과제, 위 -
List foo3
그 법적 될 모든 위의 수ArrayList
: 과제- 당신은 추가 할 수 없습니다
Integer
때문에이foo3
가리키는 수 있습니다List<Double>
. - 당신은 추가 할 수 없습니다
Double
때문에이foo3
가리키는 수 있습니다List<Integer>
. - 당신은 추가 할 수 없습니다
Number
때문에이foo3
가리키는 수 있습니다List<Integer>
.
- 당신은 추가 할 수 없습니다
List<? extends T>
어떤 종류의 객체를 List
실제로 가리키는 지 보장 할 수 없기 때문에 어떤 객체도 추가 할 수 없습니다 . 따라서 객체가 .NET에서 허용된다는 것을 보장 할 수 없습니다 List
. 유일한 "보증"은 읽기만 가능하며 T
또는의 하위 클래스를 얻을 수 있다는 것 입니다 T
.
super
이제 고려하십시오 List <? super T>
.
와일드 카드 선언은 List<? super Integer> foo3
다음 중 하나가 법적 할당임을 의미합니다.
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
읽기 -위의 가능한 할당이 주어지면 다음에서 읽을 때 어떤 유형의 객체를받을 수 있는지 보장합니다
List foo3
.- 또는을 가리킬 수
Integer
있기 때문에 보장되지 않습니다 .foo3
List<Number>
List<Object>
- 을 가리킬 수
Number
있기 때문에 a가 보장되지 않습니다 .foo3
List<Object>
- 유일한 보증은 당신이의 인스턴스를 얻을 것입니다
Object
또는 서브 클래스를Object
(하지만 서브 클래스가 무엇인지 모른다).
- 또는을 가리킬 수
쓰기 감안할 때 당신이 추가 할 수있는 개체의 유형 가능한 과제, 위 -
List foo3
그 법적 될 모든 위의 수ArrayList
: 과제- 는 위 목록에서 허용
Integer
되므로 추가 할 수 있습니다Integer
. - 위 목록에서
Integer
의 서브 클래스의 인스턴스Integer
가 허용 되기 때문에의 서브 클래스의 인스턴스를 추가 할 수 있습니다 . - 당신은 추가 할 수 없습니다
Double
때문에이foo3
가리키는 수 있습니다ArrayList<Integer>
. - 당신은 추가 할 수 없습니다
Number
때문에이foo3
가리키는 수 있습니다ArrayList<Integer>
. - 당신은 추가 할 수 없습니다
Object
때문에이foo3
가리키는 수 있습니다ArrayList<Integer>
.
- 는 위 목록에서 허용
PECS
PECS : "Producer Extends, Consumer Super"를 기억하십시오 .
"Producer Extends" - 값
List
을 생성하기 위해 를 필요로하는 경우T
(T
목록에서 s 를 읽고 자 함 )? extends T
, 예를 들어List<? extends Integer>
. 그러나이 목록에 추가 할 수 없습니다."Consumer Super" - 값
List
을 소비 해야하는 경우T
(T
목록에 s 를 작성하려는? super T
경우) 예를 들어List<? super Integer>
. 그러나이 목록에서 읽을 수있는 개체 유형에 대한 보장은 없습니다.목록에서 읽고 쓸 필요가있는 경우 와일드 카드없이 정확하게 선언해야합니다 (예 :
List<Integer>
.
예
Java Generics FAQ에서이 예를 참고 하십시오 . 소스 목록 src
(생산 목록)이를 사용 extends
하고 대상 목록 dest
(소비 목록)이 다음을 사용 하는 방법에 유의하십시오 super
.
public class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
}
또한 어떻게 목록에 추가 할 수 있습니까?를 참조하십시오 . Number> 데이터 구조를 확장합니까?
이 계층 구조가 있다고 상상해보십시오.
1. 확장
쓰기로
List<? extends C2> list;
당신은 그 말을 list
(예를 들어) 유형의 객체 참조 할 수있을 것이다 ArrayList
제네릭 형식 7 개 중 하나입니다 아형 의를 C2
( C2
포함) :
- C2 :
new ArrayList<C2>();
, (C2 또는 하위 유형을 저장할 수있는 객체) 또는 - D1 :
new ArrayList<D1>();
, (D1 또는 하위 유형을 저장할 수있는 객체) 또는 - D2 :
new ArrayList<D2>();
, (D2 또는 하위 유형을 저장할 수있는 객체) 또는 ...
등등. 7 가지 다른 경우 :
1) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<D1>(): can store D1 E1 E2
3) new ArrayList<D2>(): can store D2 E3 E4
4) new ArrayList<E1>(): can store E1
5) new ArrayList<E2>(): can store E2
6) new ArrayList<E3>(): can store E3
7) new ArrayList<E4>(): can store E4
가능한 각 경우에 대해 "저장 가능한"유형 세트가 있습니다. 여기서 그래픽으로 표현 된 7 (빨간색) 세트
보시다시피 모든 경우에 공통적 인 안전한 유형 은 없습니다 .
- 그럴 수
list.add(new C2(){});
있기 때문에 당신은 할 수 없습니다list = new ArrayList<D1>();
- 그럴 수
list.add(new D1(){});
있기 때문에 당신은 할 수 없습니다list = new ArrayList<D2>();
등등.
2. 슈퍼
쓰기로
List<? super C2> list;
당신은 그 말을 list
(예를 들어) 유형의 객체 참조 할 수있을 것이다 ArrayList
제네릭 형식 7 개 중 하나입니다 슈퍼 타입 의를 C2
( C2
포함) :
- A1 :
new ArrayList<A1>();
, (A1 또는 하위 유형을 저장할 수있는 객체) 또는 - A2 :
new ArrayList<A2>();
, (A2 또는 하위 유형을 저장할 수있는 객체) 또는 - A3 :
new ArrayList<A3>();
, (A3 또는 하위 유형을 저장할 수있는 객체) 또는 ...
등등. 7 가지 다른 경우 :
1) new ArrayList<A1>(): can store A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<A2>(): can store A2 B2 C1 C2 D1 D2 E1 E2 E3 E4
3) new ArrayList<A3>(): can store A3 B3 C2 C3 D1 D2 E1 E2 E3 E4
4) new ArrayList<A4>(): can store A4 B3 B4 C2 C3 D1 D2 E1 E2 E3 E4
5) new ArrayList<B2>(): can store B2 C1 C2 D1 D2 E1 E2 E3 E4
6) new ArrayList<B3>(): can store B3 C2 C3 D1 D2 E1 E2 E3 E4
7) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
가능한 각 경우에 대해 "저장 가능한"유형 세트가 있습니다. 여기서 그래픽으로 표현 된 7 (빨간색) 세트
당신이 볼 수 있듯이, 우리가 일곱이 개 안전 유형 모든 경우에 공통적 : C2
, D1
, D2
, E1
, E2
, E3
, E4
.
- 당신은 할 수
list.add(new C2(){});
있기 때문에,에 관계없이 우리가 참조하고 목록의 종류,C2
허용 - 당신은 할 수
list.add(new D1(){});
있기 때문에,에 관계없이 우리가 참조하고 목록의 종류,D1
허용
등등. 이러한 유형은 type에서 시작하는 계층 구조에 해당합니다 C2
.
메모
몇 가지 테스트를하려면 여기에 완전한 계층 구조가 있습니다.
interface A1{}
interface A2{}
interface A3{}
interface A4{}
interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{}
interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{}
interface D1 extends C1,C2{}
interface D2 extends C2{}
interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{}
나는 @Bert F의 대답을 좋아하지만 이것이 내 두뇌가 보는 방식입니다.
손에 X가 있습니다. 내가 원하는 경우 연락처 목록 내 X 내가 IE에서 어떤을 쓰기로 업 캐스팅 할 수있는 X의 목록 또는 물건의 목록이 될 필요가 있음, 목록에 내 X를 슈퍼 클래스 X의를 ...
List<? super X>
내가 목록을 얻고 그 목록 에서 X 를 읽고 싶다면 , 그것은 X의 목록이거나 내가 읽을 때 X로 업 캐스트 될 수있는 것들의 목록, 즉 X 를 확장하는 모든 것입니다.
List<? extends X>
도움이 되었기를 바랍니다.
Bert F의 답변을 바탕으로 내 이해를 설명하고 싶습니다.
다음과 같이 3 개의 클래스가 있다고 가정 해 봅시다.
public class Fruit{}
public class Melon extends Fruit{}
public class WaterMelon extends Melon{}
여기 우리는
List<? extends Fruit> fruitExtendedList = …
//Says that I can be a list of any object as long as this object extends Fruit.
Ok 이제 fruitExtendedList에서 값을 가져옵니다.
Fruit fruit = fruitExtendedList.get(position)
//This is valid as it can only return Fruit or its subclass.
다시 시도 해보자
Melon melon = fruitExtendedList.get(position)
//This is not valid because fruitExtendedList can be a list of Fruit only, it may not be
//list of Melon or WaterMelon and in java we cannot assign sub class object to
//super class object reference without explicitly casting it.
같은 경우
WaterMelon waterMelon = fruitExtendedList.get(position)
이제 fruitExtendedList에 객체를 설정해 보겠습니다.
과일 개체 추가
fruitExtendedList.add(new Fruit())
//This in not valid because as we know fruitExtendedList can be a list of any
//object as long as this object extends Fruit. So what if it was the list of
//WaterMelon or Melon you cannot add Fruit to the list of WaterMelon or Melon.
멜론 개체 추가
fruitExtendedList.add(new Melon())
//This would be valid if fruitExtendedList was the list of Fruit but it may
//not be, as it can also be the list of WaterMelon object. So, we see an invalid
//condition already.
마지막으로 WaterMelon 개체를 추가해 보겠습니다.
fruitExtendedList.add(new WaterMelon())
//Ok, we got it now we can finally write to fruitExtendedList as WaterMelon
//can be added to the list of Fruit or Melon as any superclass reference can point
//to its subclass object.
그러나 누군가가 새로운 유형의 레몬을 만들기로 결정하면 SaltyLemon이
public class SaltyLemon extends Lemon{}
이제 fruitExtendedList는 Fruit, Melon, WaterMelon 또는 SaltyLemon의 목록이 될 수 있습니다.
그래서 우리의 진술
fruitExtendedList.add(new WaterMelon())
또한 유효하지 않습니다.
기본적으로 우리는 fruitExtendedList에 아무것도 쓸 수 없다고 말할 수 있습니다.
이것은 요약 List<? extends Fruit>
이제 보자
List<? super Melon> melonSuperList= …
//Says that I can be a list of anything as long as its object has super class of Melon.
이제 melonSuperList에서 값을 얻으십시오.
Fruit fruit = melonSuperList.get(position)
//This is not valid as melonSuperList can be a list of Object as in java all
//the object extends from Object class. So, Object can be super class of Melon and
//melonSuperList can be a list of Object type
마찬가지로 Melon, WaterMelon 또는 다른 개체는 읽을 수 없습니다.
하지만 객체 유형 인스턴스를 읽을 수 있습니다.
Object myObject = melonSuperList.get(position)
//This is valid because Object cannot have any super class and above statement
//can return only Fruit, Melon, WaterMelon or Object they all can be referenced by
//Object type reference.
이제 melonSuperList에서 값을 설정해 보겠습니다.
개체 유형 개체 추가
melonSuperList.add(new Object())
//This is not valid as melonSuperList can be a list of Fruit or Melon.
//Note that Melon itself can be considered as super class of Melon.
과일 유형 개체 추가
melonSuperList.add(new Fruit())
//This is also not valid as melonSuperList can be list of Melon
멜론 유형 개체 추가
melonSuperList.add(new Melon())
//This is valid because melonSuperList can be list of Object, Fruit or Melon and in
//this entire list we can add Melon type object.
WaterMelon 유형 개체 추가
melonSuperList.add(new WaterMelon())
//This is also valid because of same reason as adding Melon
요약하면 melonSuperList에 Melon 또는 그 하위 클래스를 추가하고 Object 유형 객체 만 읽을 수 있습니다.
super는 하한이고 extends는 상한입니다.
http://download.oracle.com/javase/tutorial/extra/generics/morefun.html 에 따르면 :
해결책은 우리가 아직 보지 못한 경계 와일드 카드의 형태를 사용하는 것입니다 : 하한이있는 와일드 카드입니다. 구문? super T는 T의 상위 유형 (또는 T 자체; 상위 유형 관계가 반사적임을 기억하십시오) 인 알 수없는 유형을 나타냅니다. 우리가 사용했던 경계 와일드 카드의 이중입니다. T를 확장하여 T의 하위 유형 인 알 수없는 유형을 나타냅니다.
차이점을 시각화하고 싶습니다. 다음이 있다고 가정합니다.
class A { }
class B extends A { }
class C extends B { }
List<? extends T>
-읽기 및 할당 :
|-------------------------|-------------------|---------------------------------|
| wildcard | get | assign |
|-------------------------|-------------------|---------------------------------|
| List<? extends C> | A B C | List<C> |
|-------------------------|-------------------|---------------------------------|
| List<? extends B> | A B | List<B> List<C> |
|-------------------------|-------------------|---------------------------------|
| List<? extends A> | A | List<A> List<B> List<C> |
|-------------------------|-------------------|---------------------------------|
List<? super T>
-쓰기 및 할당 :
|-------------------------|-------------------|-------------------------------------------|
| wildcard | add | assign |
|-------------------------|-------------------|-------------------------------------------|
| List<? super C> | C | List<Object> List<A> List<B> List<C> |
|-------------------------|-------------------|-------------------------------------------|
| List<? super B> | B C | List<Object> List<A> List<B> |
|-------------------------|-------------------|-------------------------------------------|
| List<? super A> | A B C | List<Object> List<A> |
|-------------------------|-------------------|-------------------------------------------|
모든 경우 :
- 와일드 카드에 관계없이 항상 목록에서 가져올 수 있습니다
Object
. - 와일드 카드에 관계없이 언제든지 변경 가능한 목록에 추가 할 수 있습니다
null
.
extends 를 사용 하면 컬렉션에서만 얻을 수 있습니다. 그것에 넣을 수 없습니다. 또한 super 는 get과 put을 모두 허용 하지만 get 중 반환 유형은 ? 슈퍼 T .
목록에 항목 추가 :
목록 extends X> 는
null
목록을 제외하고는 아무것도 추가 할 수 없습니다 .목록 super X> 는 X (X 또는 하위 유형) 또는 null 인 모든 것을 추가 할 수 있습니다.
목록에서 항목 가져 오기 :
- 언제에서 항목 가져 목록 <? X>를 확장하면 X 유형의 변수 또는 Object를 포함한 X의 수퍼 유형에 할당 할 수 있습니다.
- 언제에서 항목 가져 목록 <? super X> , 당신은 유형의 변수에만 할당 할 수 있습니다
Object
.
몇 가지 예 :
List<? extends Number> list1 = new ArrayList<Integer>();
list1.add(null); //OK
Number n = list1.get(0); //OK
Serializable s = list1.get(0); //OK
Object o = list1.get(0); //OK
list1.add(2.3); //ERROR
list1.add(5); //ERROR
list1.add(new Object()); //ERROR
Integer i = list1.get(0); //ERROR
List<? super Number> list2 = new ArrayList<Number>();
list2.add(null); //OK
list2.add(2.3); //OK
list2.add(5); //OK
Object o = list2.get(0); //OK
list2.add(new Object()); //ERROR
Number n = list2.get(0); //ERROR
Serializable s = list2.get(0); //ERROR
Integer i = list2.get(0); //ERROR
당신은이 이유를 이해하기 위의 모든 답변을 통해 갈 수 .add()
제한됩니다 '<?>'
, '<? extends>'
그리고 부분적으로 '<? super>'
.
그러나 기억하고 싶고 매번 답을 탐구하고 싶지 않다면 여기에 모든 결론이 있습니다.
List<? extends A>
이 모든 동의 의미 List
의 A
의와 서브 클래스를 A
. 그러나이 목록에는 아무것도 추가 할 수 없습니다. 유형의 개체도 아닙니다 A
.
List<? super A>
의 모든 목록 A
및 수퍼 클래스를 허용합니다 A
. 유형의 개체 A
와 해당 하위 클래스를 추가 할 수 있습니다 .
여기서 가장 혼란스러운 점은 지정하는 유형 제한이 무엇이든 할당이 한 가지 방식으로 만 작동한다는 것입니다.
baseClassInstance = derivedClassInstance;
당신은 그렇게 생각 Integer extends Number
하고는 Integer
A와 할 것 <? extends Number>
,하지만 컴파일러는 당신을 말할 것이다 <? extends Number> cannot be converted to Integer
(인간의 말투에서, 그 이 수를 확장 아무것도 정수로 변환 할 수 있다는 잘못된 것입니다 ) :
class Holder<T> {
T v;
T get() { return v; }
void set(T n) { v=n; }
}
class A {
public static void main(String[]args) {
Holder<? extends Number> he = new Holder();
Holder<? super Number> hs = new Holder();
Integer i;
Number n;
Object o;
// Producer Super: always gives an error except
// when consumer expects just Object
i = hs.get(); // <? super Number> cannot be converted to Integer
n = hs.get(); // <? super Number> cannot be converted to Number
// <? super Number> cannot be converted to ... (but
// there is no class between Number and Object)
o = hs.get();
// Consumer Super
hs.set(i);
hs.set(n);
hs.set(o); // Object cannot be converted to <? super Number>
// Producer Extends
i = he.get(); // <? extends Number> cannot be converted to Integer
n = he.get();
o = he.get();
// Consumer Extends: always gives an error
he.set(i); // Integer cannot be converted to <? extends Number>
he.set(n); // Number cannot be converted to <? extends Number>
he.set(o); // Object cannot be converted to <? extends Number>
}
}
hs.set(i);
의 Integer
슈퍼 클래스로 변환 할 수Number
있기 때문에 괜찮습니다 ( true가 아닌 Integer
의 슈퍼 클래스 이기 때문 Number
이 아닙니다).
편집은 소비자가 확장 및 프로듀서 슈퍼에 대한 코멘트를 추가 -가, 대응, 지정하지 않는 때문에 의미없는 아무것도 그냥 Object
. CEPS는 유용하지 않기 때문에 PECS를 기억하는 것이 좋습니다.
일반 와일드 카드는 두 가지 주요 요구 사항을 대상으로합니다.
일반 컬렉션에서 읽기 일반 컬렉션에 삽입 일반 와일드 카드를 사용하여 컬렉션 (변수)을 정의하는 세 가지 방법이 있습니다. 이것들은:
List<?> listUknown = new ArrayList<A>();
List<? extends A> listUknown = new ArrayList<A>();
List<? super A> listUknown = new ArrayList<A>();
List<?>
알 수없는 유형으로 입력 된 목록을 의미합니다. List<A>
, a List<B>
, a List<String>
등 이 될 수 있습니다 .
List<? extends A>
class A
, 또는의 인스턴스 인 개체 목록을 의미합니다 subclasses of A
(예 : B 및 C). List<? super A>
목록이 A class
, 또는에 입력되었음을 의미합니다 superclass of A
.
더 읽기 : http://tutorials.jenkov.com/java-generics/wildcards.html
Extends 및 Super를 사용하는 경우
와일드 카드는 메소드 매개 변수에서 가장 유용합니다. 메소드 인터페이스에서 필요한 유연성을 허용합니다.
사람들은 종종 extends를 사용할 때와 super bound를 사용할 때 혼동합니다. 경험의 법칙은 get-put 원칙입니다. 매개 변수화 된 컨테이너에서 무언가를 얻는 경우 extends를 사용하십시오.
int totalFuel(List<? extends Vehicle> list) {
int total = 0;
for(Vehicle v : list) {
total += v.getFuel();
}
return total;}
totalFuel 메소드는 목록에서 Vehicles를 가져 와서 연료가 얼마나 있는지 묻고 총계를 계산합니다. 매개 변수화 된 컨테이너에 개체를 넣는 경우 super를 사용합니다.
int totalValue(Valuer<? super Vehicle> valuer) {
int total = 0;
for(Vehicle v : vehicles) {
total += valuer.evaluate(v);
}
return total;}
totalValue 메소드는 Vehicles를 Valuer에 넣습니다. extends bound가 super보다 훨씬 더 일반적이라는 것을 아는 것이 유용합니다.
찬성 된 답변은 여러 측면에 대한 세부 사항을 다룹니다. 그러나 나는 이것을 다른 방식으로 대답하려고 노력할 것입니다.
고려해야 할 두 가지 사항이 있습니다.
1. 목록 변수에 할당
List<? extends X> listvar;
여기서 X의 목록 또는 X의 하위 클래스 목록 을 listvar에 할당 할 수 있습니다 .
List<? extends Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Integer>();
List<? super X> listvar;
여기서 X의 목록 또는 X의 수퍼 클래스 목록 을 listvar에 할당 할 수 있습니다 .
List<? super Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Object>();
2. 목록 변수에서 읽기 또는 쓰기 작업을 수행합니다.
`List<? extends X> listvar;`
이 기능을 사용하여 메서드 인수의 목록을 수락하고 유형 X 에 대한 작업을 수행 할 수 있습니다 (참고 : 목록에서 X 유형의 개체 만 읽을 수 있음 ).
`List<? super Number> listvar;
이 기능을 사용하여 메서드 인수의 목록을 수락하고 Object 유형에 대한 모든 작업을 수행 할 수 있습니다 . 목록에서 Object 유형의 개체 만 읽을 수 있기 때문 입니다. 하지만 예, 여기에 추가로 X 유형의 개체를 목록에 추가 할 수 있습니다.
예를 들어 상속 순서는 O> S> T> U> V로 가정합니다.
extends 키워드 사용,
옳은:
List<? extends T> Object = new List<T>();
List<? extends T> Object = new List<U>();
List<? extends T> Object = new List<V>();
올바르지 않음 :
List<? extends T> Object = new List<S>();
List<? extends T> Object = new List<O>();
슈퍼 키워드 :
옳은:
List<? super T> Object = new List<T>();
List<? super T> Object = new List<S>();
List<? super T> Object = new List<O>();
올바르지 않음 :
List<? super T> Object = new List<U>();
List<? super T> Object = new List<V>();
객체 추가 : List Object = new List ();
Object.add(new T()); //error
하지만 왜 오류입니까? List Object 초기화 가능성을 살펴 보겠습니다.
List<? extends T> Object = new List<T>();
List<? extends T> Object = new List<U>();
List<? extends T> Object = new List<V>();
Object.add (new T ()); 다음 경우에만 정확합니다.
List<? extends T> Object = new List<T>();
하지만 두 가지 가능성이 더 있습니다.
목록 개체 = new List (); 목록 개체 = new List (); 위의 두 가지 가능성에 (new T ())를 추가하려고하면 T가 U 및 V의 상위 클래스이기 때문에 오류가 발생합니다. U 및 V 유형의 목록에 T 객체 [(new T ())]를 추가하려고합니다. 상위 클래스 개체 (기본 클래스)는 하위 클래스 개체 (하위 클래스)에 전달할 수 없습니다.
추가 두 가지 가능성으로 인해 Java는 올바른 가능성을 사용하더라도 오류가 발생합니다 .Java는 사용자가 참조하는 Object가 무엇인지 알지 못하므로 List Object = new List ();에 객체를 추가 할 수 없습니다. 유효하지 않은 가능성이 있기 때문입니다.
객체 추가 : List Object = new List ();
Object.add(new T()); // compiles fine without error
Object.add(new U()); // compiles fine without error
Object.add(new V()); // compiles fine without error
Object.add(new S()); // error
Object.add(new O()); // error
그러나 위의 두 가지에서 오류가 발생하는 이유는 무엇입니까? Object.add (new T ()); 사용할 수 있습니다. 아래 가능성에 대해서만,
List<? super T> Object = new List<T>();
List<? super T> Object = new List<S>();
List<? super T> Object = new List<O>();
List에서 Object.add (new T ())를 사용하려고했다면 Object = new List (); 및 List Object = new List (); 그러면 오류가 발생합니다. 이것은 우리가 List Object = new List ();에 T object [new T ()]를 추가 할 수 없기 때문입니다. U 유형의 객체이기 때문입니다. T는 기본 클래스이고 U는 하위 클래스이기 때문에 T 객체 [새로운 T ()]를 U 객체에 추가 할 수 없습니다. 하위 클래스에 기본 클래스를 추가 할 수 없으므로 오류가 발생합니다. 이것은 다른 경우에도 동일합니다.
참고 URL : https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java
'Nice programing' 카테고리의 다른 글
malloc과 calloc의 차이점은 무엇입니까? (0) | 2020.09.29 |
---|---|
Objective-C에서 난수 생성 (0) | 2020.09.29 |
C #에서 명령 줄 인수를 구문 분석하는 가장 좋은 방법은 무엇입니까? (0) | 2020.09.29 |
String.slice와 String.substring의 차이점은 무엇입니까? (0) | 2020.09.29 |
Objective-C에서 델리게이트를 어떻게 생성합니까? (0) | 2020.09.29 |