TIL Generics

UihyunLee·2025년 4월 18일

최근 캠프에서 Generics 에 관한 수업을 듣고 과제에 적용해보았는데 이에 관해 한번 자바의 정석 책을 보며 정리를 해보려 합니다. Ts를 사용해 개발을 할 때에는 사용해본 경험이 있는데 제대로 한번 살펴보겠습니다.

Generics란 무엇인가?

  • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능입니다. 객체의 타입을 컴파일 시에 체크하기 때문에 타입 안정성을 높이고 형변환의 번거로움이 줄어듭니다.

클래스와 메서드에 사용할 수 있으며 클래스에서 사용하는 방식을 알아보겠습니다.

class Cat<T> {
	T sound;
    
    public void setSound(T sound) {
    	this.sound = sound;
    }
    
    public T getSound(){
    	return this.sound;
    }
}

T는 타입 변수라 부르며 T가 아닌 다른 것을 사용해도 무방합니다.

위 코드를 이어서 객체화를 할 때 사용하는 방법을 보겠습니다

Cat<String> cat = new Cat<>();
cat.setSound("야옹");
String sound = cat.getSound();

Cat 클래스의 타입 T를 String 실제 타입으로 지정했기에 객체화 할 때나 혹은 T로 변수를 호출할 때 모두 String이 되어야 합니다.

만약 Cat cat = new Cat() 형식으로 제네릭 클래스가 아닌 기본의 클래스처럼 생성을 해도 만들어지지만 안전하지 않으며 경고가 발생합니다.

만약 A 이라는 타입이 존재하며 B 타입이 부모-자식 관계라고 생각을 해보겠습니다. 그렇다면 아래와 같은 코드가 가능합니다.

Cat<A> cat = new Cat<>();
cat.setSound(new A());
cat.setSound(new B());

그렇다면 타입 T에 대해서 제한을 할 수 있는 방법은 무엇일지 생각을 해봅시다.
extends가 있습니다.

class FruitBox<T extends Number> {
	...
}

인터페이스 또한 구현해야한다면
interface Eatable {}
class FruitBox<T extends Number & Eatable>
로 작성할 수 있습니다.

와일드카드는 다들 아실 것 같은데 이 또한 제네릭 타입으로써 선언할 수 있습니다.
Class Cat<?> {} 이런 형식은 Object 타입과 비슷하다고 할 수 있습니다.
그렇기에 상한제한과 하한제한을 통해 타입을 추가적으로 제한할 수 있습니다.

<? extends T> 와일드 카드의 상한제한. T와 그 자손들만 가능
<? super T> 와일드 카드의 하한 제한. T와 그 조상들만 가능 (ex T가 Student이고 Person의 자식이라면 이는 Student, Person, Object 모두 가능)

마지막으로 제네릭 메서드에 대해서 알아보겠습니다.
메서드의 선언부에 제네릭 타입이 선언된 메서드를 제네릭 메서드라 합니다.
(제네릭 메서드는 제네릭 클래스가 아닌 클래스에서도 정의 가능)

사용방법을 보겠습니다.
static <T> void sort(List <T> list, Comparator<? super T> c)
형식이 조금 독특합니다. void 라는 반환타입이 있는데 그 앞에 추가적으로 정의 되어 있습니다.

예시를 한번 보겠습니다.

public static <T extends Product> void printAll(ArrayList<T> list, ArrayList<T> list2) {
	for(Unit u : list) {
    	sout ... 
    }
}

...

class.<Product>printAll(list); 

간단히 제네릭을 알아봤습니다.
제네릭의 사용목적과 장점을 머리에 새기고 필요한 부분에서 적절히 사용하는 코드를 작성해야 할 것 같습니다.

profile
공부 기록

0개의 댓글