3 분 소요

지네릭란 ?

Generic이라는 단어가 주는 의미처럼 다양한 타입에 적용할 수 있도록 지원하는것, 타입(클래스, 인터페이스)에 정의 가능하며 메소드 정

의 또한 가능

class Box<T> {
    T item;
    
    public Box(T string) {
        this.item = string
    }
    
    public T getItem() {
        return this.item;
    }
}

위와 같이 지네릭 클래스를 선언할수 있다. 그 후 참조변수와 생성자에 타입 T대신 사용될 실제 타입을 지정해야 한다. 아래코드를 보면

객체를 선언한 타입과 대입할 데이터 타입은 일치해야한다는 것을 알 수 있다.

Box<Strirng> b = new Box<String>();
b.setItem(new Object()); //에러 String 외 다른타입은 지정불가
b.setIem("ABC"); //Ok

지네릭의 특징

  • 런타임에 발생하는 오류처리에서 발생하는 손실 비용을 최소화 할수 있따
  • Generic을 적용할 경우 별도의 변환 과정을 필요로 하지 않음
  • 다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시 타입 체크를 가능하도록함

위에 적은 세번째 특징을 알기 쉽게 아래 코드를 보면서 알아보자

public static <T extends Comparable<T>> void bubbleSort(T[] items) {
	for(int i = items.legnth - 1; i > 0 ; i--) {
		for(int j = 0; j < 1 ; j++) {
			if(items[j].compareTo(item[j+1]) > 0) {
				T item = items[j];
				items[j] = items[j+1];
				items[j+1] = item;
			}
		}
	}
}

버블 정렬은 각 항목의 비교를 통해 항목의 순서를 정렬하는 잘 알려진 알고리즘이다. 일반적인 버블 정렬 알고리즘은 하나의 타입에 대한

정렬을 수행하지만 지네릭스는 항목간 비교가 가능한 Comparable 항목이라면 정렬 가능한 일반적인 알고리즘 작성을 가능하게 한다.

즉 버블소트가 Integer 타입과 String 타입에도 정렬을 가능하게 함으로써 메소드하나로 다양한 타입의 정렬을 할수 있게 한다.

지네릭 타입의 선언

지네릭 타입의 선언은 일반 타입 선언에 타입 파라미터 < > 를 추가한 형태로 사용한다

또한 하나 이상의 타입 파라미터를 사용할 수 있다.

class Pair<K, V> {
	private K key;
	private V value;
	
	public K getKey() {
		return this.key;
	}
	
	public V getValue() {
		return this.value;
	}
}

주의 사항

  • 지네릭 타입 생성장에서는 타입 파라미터를 사용하지 않는다.
  • 참조 변수와 생성자에 주어지는 타입 파라미터는 동일해야 함.
  • 타입 파라미터의 상속 관계는 지네릭 타입 생성시 영향을 주지 않음
  • 타입 파라미터가 명확한 경우, 생성자 호출시 전달되어야 하는 타입 변수는 생략 가능

지네릭 메소드

메소드의 변수가 타입변수가 선언된 것. **클래스의 타입 매개변수와 메서드의 타입 매개변수 는 별개이다**

메소드를 시그너처의 타입 파라미터는 호출시 생략이 가능하다.

지네릭 메소드 선언

<Access Modifier> <Type Parameter List> <Return Type> Method name(Parameter list)

지네릭 메소드의 선언은 일반 메소드 선언과 동일하며, 일반화할 타입을 타입 파라미터로 선언한다. 메소드는 타입 파라미터의 목록을 가

져야 하며, 메소드 선언에 타입 파라미터 목록을 선언 해야한다.

public class GenericMethod {
	public <T> List<T> arrayToList(T[] array) {
		List<T> list = new LinkedList<T>();
		
		for(T t : array) {
			list.add(t);
		}
		
		return list;
	}
	
	public static void main(String [] args) {
		Integer[] array = {1,2,3};
		
		GenericMethod me = new  ();
		List<Integer> List = me.<Integer>arrayToList(array);
	}
}

타입 파라미터

지네릭스 타입은 타입 파라미터가 필요하며,타입 파라미터에는 기존 데이터 타입을 제외한 모든 타입을 사용 할 수 있으며, 정의되는 타입

내에서는 변수 선언의 타입으로 사용된다.

타입 파라미터 명명규칙

  • E : 요소 (Element)
  • K : 키 (Key)
  • N: 숫자 (Number)
  • T: 타입 (Type)
  • V: 값 (Value)
  • S,U,V 등 - 2번째, 3번째, 4번째 등

E(element)는 그 의미로 요소라고 해석할 수 있다.

예를 들어 ArrayList는 요소들(오브젝트)를 배열처럼 저장 하기 때문에 E로 선언되어야 한다.

즉, List에서는 E(Element) 가 어울린다.

결론은 컬렉션 클래스와 같이 배열 기반으로 되어 있는 구조에는 E가 어울리고, 그 외에는 T 가 어울린다.

와일드 카드

와일드 카드는 지네릭을 정의할 때 return 값에 대한 특정한 타입 파라미터를 정의하지 않고 임의의 타입이 올 수 있는 기능을 제공한다.

지네릭 파라미터의 와일드 카드는 <?> 형식으로 정의되며, 인자로 받을 수 있는 타입의 제한이 가능하다

<? extends T> : 상한 경계 : T 클래스를 상속하는 자식클래스들만 올 수 있다.

<? super T> : 하한 경계 : T 클래스의 부모 클래스만 올 수 있다. (더 제한적임)

<?> = <? extends Object> : 기존 경계 : 오브젝트 타입을 상속하는 모든 타입이 들어올 수 있다.

타입 파라미터 제약

  • 타입 파라미터 인자로 기본 데이터 타입을 사용할 수 없음

  • 타입 파라미터 변수의 객체를 생성할 수 없음

  • static 필드로 선언할 수 없음

  • 지네릭 타입은 타입변환 될 수 없으며 instance of 연산자를 사용 할 수없음

  • 지네릭 타입의 배열은 생성할 수 없음

  • Exception 타입의 서브 타입이 될 수 없음

태그:

카테고리:

업데이트: