[ 출처: http://effective.springnote.com/pages/1616988 ]
Generics 파라메터 타입
<T> : 자료형(Type) 으로 쓰일때 ...
<E> : 객체 내에서 하나의 요소(Element)로 사용될때
<K> : 전달 되는 객체가 키(Key) 값으로 사용될때
<V> : 전달 되는 객체가 값(Value) 으로 사용될때
<?> : 와일드카드 (unknown)
<? super 객체> : 제한된 와일드카드 (해당 객체 또는 상위 객체)
<? extends 객체> : 제한된 와일드카드 (해당 객체 또는 하위 객체)
sun 튜토리얼 http://java.sun.com/docs/books/tutorial/extra/generics/index.html
- 기존 방식
- List myIntList = new LinkedList();
- myIntList.add(new Integer(0));
- Integer x = (Integer) myIntList.iterator().next(); // 성가신 캐스팅
generics- List<Integer> myIntList = new LinkedList<Integer>();
- myIntList.add(new Integer(0));
- Integer x = myIntList.iterator().next();
- java.util 패키지에 있는 List 와 Iterator 의 선언부
- public interface List<E>{
- void add(E x);
- Iterator<E> iterator();
- }
- public interface Iterator<E>{
- E next();
- boolean hasNext();
- }
gerneric 방식으로 타입인자를 선언한 것으로 List<Integer>는 Integer 대신 String을 사용할 수 없지만
이경우 에는 한번만 컴파일 되면 어떤 Element 라도 사용할수 있다.
- Generics 과 하위 타입
- List<String> ls = new ArrayList<String>(); // ArrayList 는 List의 하위 타입
List<Object> lo = ls; // List<String>은 List<Object>의 하위타입이 아니다. - lo.add(new Object());
String s = ls.get(0); // error
- Wildcards
- // 기존 방식
- void printCollection(Collection c) {
- Iterator i = c.iterator();
- for (k = 0; k < c.size(); k++) {
- System.out.println(i.next());
- }
- }
- // 새로운 방식 - Collection<Obect> 만 처리 가능
- void printCollection(Collection<Object> c) {
- for (Object e : c) {
- System.out.println(e);
- }
- }
- // wildcards 사용 ( collection of unknown )
- void printCollection(Collection<?> c) {
- for (Object e : c) {
- System.out.println(e);
- }
- }
- // 임의의 Object를 add 하는 것은 안전하지 않다.
- Collection<?> c = new ArrayList<String>();
- c.add(new Object()); // Compile time error
- Bounded Wildcards
- // any kind of shape
- public void drawAll(List<? extends Shape> shapes) {
- ...
- }
- Generic Methods
- // biginner's mistake
- static void fromArrayToCollection(Object[] a, Collection<?> c) {
- for (Object o : a) {
- c.add(o); // Compile time error
- }
- }
- // generic method type declaration
- static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
- for (T o : a) {
- c.add(o); // Correct
- }
- }
- Object[] oa = new Object[100];
- Collection<Object> co = new ArrayList<Object>();
- fromArrayToCollection(oa, co); // T inferred to be Object
- String[] sa = new String[100];
- Collection<String> cs = new ArrayList<String>();
- fromArrayToCollection(sa, cs); // T inferred to be String
- fromArrayToCollection(sa, co); // T inferred to be Object
- Integer[] ia = new Integer[100];
- Float[] fa = new Float[100];
- Number[] na = new Number[100];
- Collection<Number> cn = new ArrayList<Number>();
- fromArrayToCollection(ia, cn); // T inferred to be Number
- fromArrayToCollection(fa, cn); // T inferred to be Number
- fromArrayToCollection(na, cn); // T inferred to be Number
- fromArrayToCollection(na, co); // T inferred to be Object
- fromArrayToCollection(na, cs); // compile-time error
// 언제 generic 메쏘드를 사용하고 어떤때 wildcards 타입을 사용할 것인가?
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
-
// generic 메쏘드를 사용하면 다음과 같다
interface Collection<E> {
public <T> boolean containsAll(Collection<T> c);
public <T extends E> boolean addAll(Collection<T> c);
}
- // generic 메쏘드는 두개 이상의 인자 사이의 타입 연관성을 위해 정의 된것이다. 또, wildcard는 인자의 하위 유연성을 위해 만들어졌다.
- // 다음과 같이 혼용해서 사용하는 경우도 있다.
class Collections { - public static <T> void copy(List<T> dest, List<? extends T> src) { ...}
- }
- // wildcard 를 사용하지 않고 정의 하는 방법도 있다.
class Collections { - public static <T, S extends T> void copy(List<T> dest, List<S> src) { ...}
- }
- // 첫번짹 타입인자 T는 첫 번째 메쏘드 인자의 선언부와 두번째 타입인자 S를
- // 정의하기 위한 부분에 쓰였다.
- // S는 src의 타입을 정의 하기 위해 한번만 쓰였다.
- // 즉 S는 두번째 타입인자를 정의 하기 위한 곳 외에는 쓰이지 않았다.
- // 다른 곳에서 쓰이지 않았기 때문에 S는 wildcard로 변환 될수 있다.
- // 이런 경우 wildcard를 쓰는 것이 훨씬 명확하다.
- true or false ?
- List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
-
// erasure 에 의해 모든 타입 인자가 제거되므로 의미 없는 비교이다.
- // generics 클래스 인스턴스 인지 체크 하는 것은 불가 하다.
- Collection cs = new ArrayList<String>();
- if (cs instanceof Collection<String>) { ...}
--------------------------------------------------------------------------------------------------
'IT_Programming > Java' 카테고리의 다른 글
JTable과 DB 연동 예제 (SQL Server 2005 Express Edition) (0) | 2009.04.08 |
---|---|
[펌_ jdbc] ResultSet 크기 구하기 (0) | 2009.04.08 |
웹 브라우저 실행하기 (0) | 2009.02.03 |
[펌] JDBC 별 드라이버 사용법 (0) | 2009.01.30 |
[펌] 제네릭스 해부, Part 2 (0) | 2009.01.22 |