본문 바로가기

WEB_Programming/Pure Java

Generics > Defining Simple Generics


List와 Iterator를 java.util패키지에서 지정한 내용을 발췌한 것이다.
public interface List <E>{
void add(E x);
Iterator<E> iterator();
}

public interface Iterator<E>{
E next();
boolean hasNext();
}

이 코드는 모두 익숙한 코드이다. < 을 제외하고 말이다. 여기에는 포맷 타입 파라미터를 설정하는 것으로 인터페이스인 List와 Iterator 에 지정하고 있다.

타입 파라미터는 generics 선언을 통해서 이용할 수 있으며, 일반적인 타입을 이용할때 매우 유용하다. 중요한 제약을 원하는 경우 The Fine Print.부분을 참조하면 된다.

소개에서 우리는 List<Integer>처럼 리스트의 generic 타입을 지정하는 것을 봤다. invocation에서 (보통 parameterized type라고 불려진다.) 발생되는 모든 파라미터 타입은 실제 파라미터 값으로 대체된다.

List<Integer>을 통해서 E의 내용이 Integer로 대체 되었다.

public interface IntegerList {
void add(Integer x);
Iterator<Integer> iterator();
}
이러한 직괒적인 면은 상당히 도움을 줃 그라나 여기에는 오해를 줄 수 있다.

이것은 유용하다. 왜냐하면 parameterized타입으로 List<Integer>은 사실 이방식은 단순하게 눈으로 확인하는것만으로도 어떠한 기능을 수행하는지 알 수 있기 때문이다.

It is misleading, because the declaration of a generic is never actually expanded in this way. There aren't multiple copies of the code--not in source, not in binary, not on disk and not in memory. If you are a C++ programmer, you'll understand that this is very different than a C++ template.

generic 타입 선언은 전체적으로 한번만 컴파일 된다. 그리고 단일 클래스 파일로 변경된어 일반 클래스 혹은 인터페이스 정의와 같이 변경이 된다.

타입 파라미터는 일반적인 파라미터처럼 메소드 혹은 생성자에서 이용된다. 파라미터는 형식 파라미터가 들어가게 된다.
메소드가 호출되면, actual arguments가 형식 파라미터를 대체해서 처리가 된다. 그리고 메소드 바디는 검증되게 된다. generic 선언이 호출되면 실제 타입 아규면트가 형식 파라미터를 대체하게 된다.

이름 규칙을 지정할때, 보통 형식파라미터라고 생각할 수 있도록 단일 문자를 주로 이용하게 된다. 이것은 일반 클래스와 인터페이스에서 형식 파라미터와 쉽게 구분할 수 있도록 해준다. 많은 컨테이너 타입은 E를 이용하고 있다. 상단 예제에서 처럼 말이다.