참치코더의 꿈 메모장

2021/08/26 Java - Generics(지네릭스) 본문

JAVA

2021/08/26 Java - Generics(지네릭스)

참치깡 2021. 8. 26. 20:27
728x90

Generics (지네릭스)

 

지네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다.

객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.

 

타입 안정성을 높인다는 것은 의도하지 않은 타입의 객체가 저장되는 것을 막고, 저장된 객체를 꺼내올때 

원래의 타입과 다른 타입으로 잘못 형변환되어 발생할 수 있는 오류를 줄여준다는 뜻이다.

 

지네릭스의 장점

1. 타입 안정성을 제공한다.

2. 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해 진다.

 

지네릭 클래스의 선언

 

지네릭 타입은 클래스와 메서드에 선언할 수 있다.

 

1
2
3
4
5
6
class Ex<T>{
    T item;
 
    void setItem(T item) {this.item = item;}
    T getItem() {return item;}
}
cs

 

* 사용하려는 형 대신에 사용하면 된다.

 

T를 타입 변수라고 하며, Type의 첫 글자에서 따온 것이다.

타입 변수는 T가 아닌 다른 것을 사용해도 된다.

 

타입 변수 E  : Elememt(요소)

타입 변수 K :  Key(키)

타입 변수 V : Value(값)

 

무조건 T를 사용하기 보다는 상황에 맞게 의미있는 문자를 선택해서 사용하는 것이 좋다.

 

지네릭스의 용어

1
class Ex<T>{}
cs

 

Ex<T> : 지네릭 클래스

T        : 타입 변수 또는 타입 매개변수. (T는 타입 문자)

Ex       : 원시 타입

 

* 지네릭은 메서드에 매개변수로 넘겨주는 것과 같은 형식이다.

 

지네릭 클래스에 형을 대입하고 컴파일하면  그 형에 맞는 원시타입이 만들어 지고 지네릭 타입이 제거된다.

 

지네릭스의 제한

 

모든 객체에 대해 동일하게 동작해야 하는 static멤버에 타입 변수 T를 사용할 수 없다.

T는 인스턴스변수로 간주되기 때문이다.

 

* static 멤버는 타입 변수에 지정된 타입, 대입된 타입의 종류에 관계없이 동일한 것이어야 한다.

 

지네릭 타입의 배열을 생성하는 것도 허용되지 않는다.

 

지네릭 클래스의 객체 생성과 사용

 

JDK 1.7부터 추정이 가능한 경우 타입을 생략할 수 있게 되었다.

참조변수의 타입으로부터 저장한다는 것을 알 수 있기 때문에 생성자에 반복해서 타입을 지정해 주지 않아도 된다.

 

제한된 지네릭 클래스

 

지네릭 타입에 extends를 사용하면 특정 타입의 자손들만 대입할 수 있게 제한할 수 있다.

1
2
3
class Ex<extends childEx>{
    ArrayList<T> list = new ArrayList<T>();
}
cs

 

 

다향성에서 조상타입의 참조변수로 자손타입의 객체를 가리킬 수 있는 것처럼, 

매개변수화된 자손 타입도 가능하다.

 

와일드 카드

 

static 이 붙은 메서드는 지네릭스를 가진 매개변수를 가지지 못하는데 (인스턴스 변수 참조 못함)

이렇게 되면 선언한 매개변수만 가질수 있게 된다.

 

선언한 매개변수만 가질 수 있다면 다른 지네릭 타입으로 선언한 객체는 이 static 함수의 매개변수에 

대입을 할수 없게 된다.

 

따라서 똑같은 메서드를 여러번 선언해서 오버로딩을 시도하는 방법을 생각할 수 있는데

지네릭스는 컴파일 할때 컴파일러에서 자동 삭제되므로 오버로딩이 되지 않아 중복 메서드를 사용한 것으로

간주된다. 

 

따라서 이러한 현상을 예방하기 위해 또는 유동적으로 사용하기 위해 와일드 카드가 사용된다.

 

와일드 카드는 기호 ?로 표현하는데, 와일드 카드는 어떠한 타입도 될수 있다. 

 

?만으로는  Object타입과 다를 게 없으므로, extends와 super로 상한과 하한을 제한할 수 있다.

 

<? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능

<? super T> : 와일드 카드의 하한 제한, T와 그 조상들만 가능 

<?> : 제한 없음. 모든 타입이 가능 

 

지네릭 메서드

 

메서드의 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라고 한다.

지네릭 타입의 선언위치는 반환타입 바로 앞이다.

 

static <T> void sort(List<T> list, Comparator<? super T> c)

 

지네릭 클래스에 정의된 타입 매개변수와 지네릭 메서드에 정의된 타입 매개변수는 전혀 별개의 것이다.

 

* static멤버에는 타입 매개변수를 사용할 수 없지만 , 메서드에 지네릭 타입을 선언하고 사용하는 것은 

  가능하다.

* 지네릭 메서드를 호출할 때 , 대입된 타입을 생략할 수 없는 경우에는 참조변수나 

  클래스 이름을 생략할 수 없다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void A(ArrayList<extends Product> list,
                     ArrayList<extends Product> list2){
    for(Unit u : list){
        System.out.println(u);
    }
}
 
//////////////////////////////////////////////////////////////
 
// 위의 코드를 아래와 같이 간단하게 만들 수 있다.
 
public static <extends Product> void A(ArrayList<T> list,
                                         ArrayList<T> list2) {
 
    for(Unit u : list){
        System.out.println(u);
    }
}
cs

 

728x90
Comments