나는 사이의 차이에 대한 오해 것 같다 <Foo>
와 <? extends Foo>
. 우리가 이해했다면
ArrayList<Foo> foos = new ArrayList<>();
이는 유형의 객체 Foo
가이 배열 목록에 추가 될 수 있음을 나타냅니다 . 의 서브 클래스 Foo
도 유형 Foo
이므로 다음과 같이 오류없이 추가 할 수 있습니다.
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
어디서 Bar extends Foo
?
이제 다음 foos
과 같이 정의했다고 가정 해보십시오 .
ArrayList<? extends Foo> foos = new ArrayList<>();
나의 현재 이해는 이것이 표현한다는 것입니다 some unknown type that extends Foo
. 서브 클래스 인 객체 Foo
를이 목록에 추가 할 수 있음 을 의미 합니다. ArrayList<Foo>
와 사이에 차이가 없음을 의미합니다 ArrayList<? extends Foo>
.
이것을 테스트하기 위해 다음 코드를 작성하려고했습니다.
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
그러나 다음 컴파일 오류가 표시되었습니다.
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)
no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)
나의 현재 이해에 기초하여, 나는 왜 자신의 서브 클래스가 아니기 때문에 Foo
의 목록에 a 를 추가 할 수 없는지 알 수 <? extends Foo>
있다. 하지만 왜 Bar
목록에 추가 할 수 없는지 궁금 합니다.
내 이해의 구멍은 어디에 있습니까?
답변
당신이 스스로 발견 한 것처럼 ArrayList
선언은 ArrayList<? extends Foo> subFoos = new ArrayList<>();
별로 유용하지 않습니다.
유용성을 확인하려면 다음을 <? extends T>
고려하십시오.
List<Foo> collect( List<? extends Foo> a1, List<? extends Foo> a2 )
{
List<Foo> collected = new ArrayList<>();
collected.addAll( a1 );
collected.addAll( a2 );
return collected;
}
나중에 다음과 같이 사용할 수 있습니다.
List<Foo> foos = collect( new ArrayList<Foo>(), new ArrayList<Bar>() );
또는 다음과 같이 :
List<Foo> foos = collect( new ArrayList<Bar>(), new ArrayList<Foo>() );
collect
메소드가 다음과 같이 선언 된 경우 위의 어느 것도 작동하지 않습니다 .
List<Foo> collect( List<Foo> a1, List<Foo> a2 )