Genericby Seㅈoong
Generic 알아보기!
제네릭(Generic)
- java 1.5(5.0) 부터 추가된 문법으로, 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법이다.
주로 컬렉션 클래스 컴파일 타임에 자료형의 안정성을 보장하기 위해 사용한다.
제너릭 클래스
- 특징
- 클래스 선언에 형식 타입 파라미터(Formal Type Parameter)가 포함된 클래스
- 클래스 사용시 타입정보를 인자로 전달 받는다는 의미로 매개변수화된 타입(parameterized type)라고 부르기도 한다. 같은 맥락으로 일반 클래스는 원천타입(Raw type)라고 부른다.
- 실제 타입(Actual Type)정보는 해당 클래스타입의 레퍼런스변수 선언 및 인스턴스 생성시에 제공된다.
- 제네릭 클래스의 예: ArrayList
public class ArrayList extends AbstractList`` implements List``, RandomAccess, Cloneable, java.io.Serializable{
public boolean add(E e)
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
}
- E: Element / K-V: Key-Value / N: Number / T: 일반적인 제네릭 타입
- 제네릭 클래스 생성:
제네릭 클래스 선언, 생성시 모두 실제 타입(Actual Type)을 넘겨줘야 한다.
List<String> list = new ArrayList<String>()
제네릭 메소드
- 메소드 선언에 형식 타입 파라미터(Formal Type Parameter)가 포함된 메소드
- 클래스 범위가 아닌 특정 메소드에 대해서만 제네릭 사용이 가능하다.
- 클래스 제네릭과는 다르게 형식타입 식별자가 반환타입 앞에 명시된다.
와일드 카드 <?>
- 형식 타입 파라미터에 와일드 카드 ?를 사용하면 모든 실제타입사용가능
- 실제타입의 제네릭 인스턴스 뿐만 아니라 실제타입과 상속관계에 있는 타입의 제네릭 인스턴스를 참조할 수 있다.
- ? extends Parent: Parent를 상속하는 실제 타입
- ? super Child: Child가 상속하는 실제 타입
- 참고 자료: 와일드 카드가 필요한 이유
제네릭 상속
- 상위 클래스의 형식 타입 유지 상속: Child는 제네릭 클래스를 유지
class Child<T> extends parent<T>
- 상위 클래스의 실제 타입을 지정해 상속: Child는 String을 실제타입으로 갖는다.
class Child extends parent<String>
특징
- 클래스 제네릭의 형식 타입 파라미터는 static(변수, 메소드, 블럭)에서 사용할 수 없다. 제네릭 클래스의 형식 타입의 실제 타입은 외부에서 제네릭 클래스 타입을 선언하거나 생성할 때 결정되기 때문에 클래스가 메모리에 올라갈때 이미 실행되는 static문에서는 실제타입을 알 수 없다.
- 런타임에 형식 타입 파라미터 검사가 불가능하다. 제네릭타입은 컴파일 타임에만 유효하고 런타임에는 존재하지 않는다.
컴파일 오류:
ArrayList<String> list = new ArrayList<String>();
if(list instanceof ArrayList<String>){
return "같은 타입"
}
- 둘 이상의 형식 타입 파라미터를 사용할 수 있다.
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
...
- 참조 데이터 타입만 허용한다.
- 형식 타입 파라미터를 특정 클래스를 상속하거나 상속받은 클래스로 제한할 수 있다.(extends, super)
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
...
- 제네릭 클래스내에서 형식 타입으로 인스턴스 생성시 컴파일 애러가 발생한다.
더 알고싶다.
제네릭 메소드에서 와일드 카드 사용시 리턴타입 앞에 형식 타입을 명시하는것과 파라메터에 명시하는것의 차이에 대해서 더 알아봐야겠다.
Published 01 March 2015