상위 경계 와일드카드를 사용한 객체에서는 요소를 추가할 수 없다.
ArrayList<? extends Number> foo = new ArrayList<Integer>();
foo.add(23); //compile error
미확인 종류의 큐가 전달되었으르 때 어떤 타입의 객체를 저장할 수 있는지 알 방법이 없다.
Number n = foo.remove()는 가능하다.
하위 경계 와일드카드를 사용한 객체에서는 요소를 추가할 수 있다.
ArrayList<? super Integer> bar = new ArrayList<Number>();
bar.add(42);
클래스가 확장하거나 구현하는 매개변수화된 타입에서 타입인자는 와일드카드를 사용하지 않는 구현타입이어야 한다
extends나 implements 문에서 클래스나 인터페이스를 명명하는데 사용할 수는 없다.
ArrayList<? extends Number> foo = new ArrayList<Integer>();
foo.add(23); //compile error
미확인 종류의 큐가 전달되었으르 때 어떤 타입의 객체를 저장할 수 있는지 알 방법이 없다.
Number n = foo.remove()는 가능하다.
하위 경계 와일드카드를 사용한 객체에서는 요소를 추가할 수 있다.
ArrayList<? super Integer> bar = new ArrayList<Number>();
bar.add(42);
클래스가 확장하거나 구현하는 매개변수화된 타입에서 타입인자는 와일드카드를 사용하지 않는 구현타입이어야 한다
extends나 implements 문에서 클래스나 인터페이스를 명명하는데 사용할 수는 없다.
class Foo<? extends Number>{
}
public E[] toArray() {
int size = 0;
for (Cell c = head; c != null; c.getNext()) {
size++;
}
// 타입 매개변수를 인스턴스화 하거나 배열을 생성할 수 없다.
E[] arr = new E[size];
return arr;
}
// 타입 변수 E를 가진 배열을 생성하는 것은 불가능하기 때문에 메소드를 호출하는 곳에서 적당한 크기와 타입을 가진
// 배열을 전달해야 한다는 것을 알았다.
public E[] toArray_v1(E[] arr) {
int i = 0;
for (Cell c = head; c != null; c = (Cell) c.getNext()) {
arr[i++] = c.getElement();
}
return arr;
}
/*
* 메소드에서는 T가 무슨 타입인지 신경쓰지 않고 있다.
* Object[]로 참조하고 있다는 점이 중요하다.
* 베열타입은 T이고 getElement() 리턴타입은 E이기 때문에 서로 다르다.
* 그래서 E가 String이더라도, T가 Object가 될 수 있으므로
* Object[]를 사용하여 String을 저장할 수 있도록 해야한다.
* T와 E의 타입검사는 컴파일 시간에 일어나지 않는다. 런타임시간에 일어난다.
*/
public <T> T[] toArray_v2(T[] arr) {
Object[] tmp = arr;
int i = 0;
for (Cell c = head; c != null; c = (Cell) c.getNext()) {
tmp[i++] = c.getElement();
}
return arr;
}
'JAVA이야기' 카테고리의 다른 글
와일드카드 캡쳐 (0) | 2011.07.17 |
---|---|
제네릭 메소드 호출과 타입 추정 (0) | 2011.07.16 |
[java] 배열과 타입 (0) | 2011.07.16 |
마커 인터페이스 (0) | 2011.07.16 |
인터페이스 확장 (0) | 2011.07.16 |