Java Generic

시루봉로·2023년 3월 11일
0

Java 정리

목록 보기
2/2
post-thumbnail

제네릭

자바에서의 모든 변수는 자료형이 있다. 대부분 하나의 자료형으로 구현하지만, 변수나 메서드의 자료형을 필요에 따라 여러 자료형으로 바꿀 수 있다면 프로그램이 훨씬 유연할 것이다. 이와 같이 어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍하는 것을 '제네릭(Generic) 프로그래밍'이라고 한다.
제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 즉, 타입에 대한 정보를 동적으로 넘겨줄 수 있다. 또한 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스의 컴파일 시 타입 체크를 해주는 기능이다. 이러한 점으로 인해 제네릭은 형변환이 필요없고 타입 안정성이 보장되며, 코드의 재사용성이 높아진다.

public class Test<T> {    // 제네릭 클래스 
	private T testSource;
    
    public void setTestSource(T testSource) {
    	this.testSource = testSource;
    }
    
    public T getTestSource() {
    	return testSource;
    }
}

코드를 보면 여러 자료형으로 바꾸어 사용할 testSource 변수의 자료형을 T라고 썼다. 이때 T를 자료형 매개변수(type parameter)라고 부른다. 클래스 이름을 Test라고 정의하고 나중에 클래스를 사용할 때 T 위치에 실제 사용할 자료형을 지정한다. 클래스의 각 메서드에서 해당 자료형이 필요한 부분에는 모두 T 문자를 사용하여 구현한다.

Test<Ex1> test1 = new Test<Ex1>();
test1.setTestSource(new Ex1());

Test<Ex2> test2 = new Test<Ex2>();
test2.setTestSource(new Ex2());

또한 제네릭은 아래 표의 타입들이 많이 쓰인다. 그러나 반드시 이 타입대로 하지 않아도 된다. 대중적으로 통하는 통상적인 선언이 가장 편하기에 아래와 같은 규칙이 있을 뿐이다.

<T>: Type
<E>: Element
<K>: Key
<V>: Value
<N>: Number

자료형 매개변수

제네릭 메서드의 일반 형식은 다음과 같다.

public <자료형 매개변수> 반환형 메서드이름 (자료형 매개변수){}

이때 반환형 앞에 사용하는 <자료형 매개변수>는 여러 개일 수 있으며, 이는 메서드 내에서만 유효하다.

public class Point<T, V> {
    T x;
    V y;
      
    Point(T x, V y) {
        this.x = x;
        this.y = y;
    }
      
    public T getX() {
        return x;
    }
      
    public V getY() {
    	return y;
    }
}

한 점을 나타내는 Point 클래스의 두 좌표 x, y는 자료형이 불분명하기에 T와 V라는 자료형 매개변수로 표현했다. 그리고 이 변수들을 위한 getX(), getY() 메서드에서 T와 V를 반환하고 있기에 제네릭 메서드이다. 이 Point 클래스를 활용하여 다음과 같이 두 점을 생성할 수 있다.

Point<Integer, Double> p1 = new Point<>(0, 0.0);

<T extends 클래스>

제네릭 클래스에서 T 자료형에 사용할 자료형에 제한을 둘 수 있다. 예를 들어 SeaFood 클래스에는 음식 재료가 한정되어 있다. 만약 제약이 없다면 돼지고기나 소고기가 음식 재료로 쓰여 해산물 요리를 선보일 수 없게 된다. 이런 일을 방지하기 위해 사용할 클래스에 자료형 제한을 두는 방식으로 extends 예약어를 사용할 수 있다.

public class SeaFood<T extends fish> { // 생선류로 제한을 둠
	private T fish;
	...
}

와일드 카드 <?>

제네릭의 T 자료형에 사용할 자료형에 제한을 주려면 extends와 super 그리고 ?가 필요하다. 이때 ?가 와일드 카드이며, 쉽게 말해 알 수 없는 타입이다.

<K extends T> // T와 T의 자손 타입만 가능 (K는 들어오는 타입으로 지정됨)
<K super T> // T와 T의 부모 및 조상 타입만 가능 (K는 들어오는 타입으로 지정됨)

<? extends T> // T와 T의 자손 타입만 가능
<? super T> // T와 T의 부모 및 조상 타입만 가능
<?> // 모든 타입 가능, <? extends Object>랑 같은 의미

보통 이해하기 쉽게 extends T는 상한 경계라 부르며, ? super T는 하한 경계라 부른다.

졸리니까 다음에 작성하도록 하자.


참고 자료

본 글은 아래 링크를 기반으로 정리하였습니다.

profile
안녕하세요.

0개의 댓글