본문 바로가기

JAVA/자바의정석

자바(JAVA) - 지네릭스(Generics)

728x90
반응형

지네릭스(Generics)

[1] 지네릭스란?

컴파일시 타입을 체크해 주는 기능

지네릭스는 '매개변수화된 자료형' 이다. 지네릭스는 클래스, 인터페이스 또는 메소드에 적용될 수 있는데, 클래스에 적용되면 제네릭 클래스, 인터페이스에 적용되면 제네릭 인터페이스, 메소드에 적용되면 제네릭 메소드라고 부른다. 

객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여준다.

장점
1. 타입 안정성을 제공한다.
2. 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해 진다.

 

[2] 지네릭 클래스의 선언

지네릭타입은 클래스와 메서드에 선언할 수 있는데, 먼저 클래스에 선언하는 지네릭 타입에 대해 알아보겠다.

class Box{
	Object item;
	
	void setItem(Object item) {
		this.item = item;
	}
	Object getItem() {
		return item;
	}
}

이 클래스를 지네릭 클래스로 변경하면 다음과 같이 클래스 옆에 '<T>'를 붙이면 된다.

그리고 'Object'를 모두 'T'로 바꾼다.

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

Box<T> 에서 T를 타입변수 라고 하며 타입변수는 상황에 맞게 의미 있는 문자를 선택해서 사용한다.

ArrayList<E> 의경우 E가 타입변수이다.

이들은 기호의 종류만 다를 뿐 '임의의 참조형 타입'을 의미한다는 것은 모두 같다.

T가 String 일경우 Box 클래스에 String타입만 담을 수 있다.

 

지네릭스의 용어

class Box<T> {}
Box<T> 지네릭 클래스. 'T의 Box' 또는 'T Box'라고 읽는다.
T          타입변수 또는 타입 매개변수. (T는 타입문자)
Box       원시타입(raw type)

지네릭 타입 호출

Box<String> b = new Box<String>();

지네릭스의 제한

객체별로 다른타입을 지정해 줄 수 있다.

Box<Apple> appleBox = new Box<Apple>;	// Apple 객체만 저장 가능
Box<Grape> grapeBox = new Box<Grape>;	// Grape 객체만 저장 가능

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

지네릭타입의 객체를 생성할때는 참조변수와 생성자에 대입된 타입(매개변수화된 타입)이 일치해야 한다.

일치하지 않으면 에러가 발생한다.

 

[4] 제한된 지네릭 클래스

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

인터페스만 구현해야 한다는 제한이 필요할때도 'extends'를 사용한다. 'implements'를 사용하지 않는다는 점에 유의한다.

 

[5] 와일드 카드

지네릭 타입을 다르게 오버로딩 하면 컴파일 에러가 발생한다. 지네릭 타입이 다른 것만으로는 오버로딩이 성립하지 않기 때문이다. 그래서 오버로딩이 아니라 메서드 중복 정의로 인식하게 된다.

이럴 때 사용하기 위해 고안된 것이 '와이들 카드' 이다. 와일드 카는 기호 '?'로 표현하는데, 와일드 카드는 어떠한 타입도 될 수 있다.

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

<? extends T>   와일드 카드의 상한 제한, T와 그 자손들만 가능
<? super T>      와일드 카드의 하한 제한, T와 그 조상들만 가능
<?>                   제한 없음. 모든 타입이 가능 <? extends Object>와 동일

 

 

[6] 지네릭 메서드

메서드의 선언부에 지네릭 타입이 선언된 메서드.

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

 

728x90
반응형