Java

[JAVA] 자바 - 제네릭의 기본 문법

Seong-Jun 2025. 2. 20. 11:18
728x90
반응형
SMALL

다중 매개변수 기반 제네릭 클래스의 정의하기

class DBox<L, R> {
	private L left; // 왼쪽 수납 공간
	private R right; // 오른쪽 수납 공간
	public void set(L o, R r) {
		left = o;
		right = r;
	}
	@Override
	public String toString() {
		return left + " & " + right;
	}
}

public static void main(String[] args) {
	DBox<String, Integer> box = new DBox<String, Integer>();
	box.set("Apple", 25);
	System.out.println(box); // => Apple & 25 출력!
}

 

DBox 클래스에 제네릭을 <String, Integer>로 설정했으므로 L => String, R => Integer가 된다.

타입 매개변수의 이름 규칙은?

=> 이름은 한 문자이고 대문자로 작성하는 것이 관례이다

보편적인 선택

E Element
K Key
N Number
T Type
V Value

 

기본 자료형에 대한 제한 => Wrapper 클래스 사용하기

Box<int> box = new Box<int>();

=> 타입 인자로 기본 자료형이 올 수 없으므로 컴파일 오류 발생하므로 아래와 같이 생성 가능

Box<Integer> box = new Box<>();
// 다이아몬드 기호!!
// 생성할 때 타입은 생략 가능!
// => 참조 변수 선언을 통해서 컴파일러가 타입을 유추함!

제네릭 클래스의 타입 인자 제한하기

class Box<T extends 클래스명 혹은 인터페이스명> {...}
  • <T> : 어떤 타입 파라미터든 허용
  • <T extends 클래스 또는 인터페이스> : 부모 타입을 상속받은 자식 클래스만 허용
    • <T extends 클래스A> : 클래스A, 또는 클래스A의 상속받은 클래스만 허용
           => 클래스 하나만 작성 가능하고 final로 선언되지 않은 클래스이어야 함
           => final로 선언된 클래스는 다른 클래스가 상속 받을 수 없기 때문이다
    • <T extends 인터페이스A> : 인터페이스A를 구현(상속)한 클래스만 허용(인터페이스 여러개 작성 가능함)
  • <T extends 클래스A & 인터페이스A> : 클래스A를 상속받고 인터페이스A를 구현한 클래스만 허용 

=> 제네릭 타입에 extends 키워드를 사용하여 클래스일 경우 T가 해당 클래스를 상속하고 있는 타입으로 제한한다. 인터페이스일 경우 T가 해당 인터페이스를 구현하고 있는 타입으로 제한한다.

(클래스일 경우 해당 클래스도 포함됨)

class Box<T extends Number> {
    private T ob;
    public void set(T o) {
    	ob = o;
    }
    public T get() {
    	return ob;
    }
}

public static void main(String[] args) {
    Box<Integer> iBox = new Box<>();
    iBox.set(24);
    Box<Double> dBox = new Box<>();
    dBox.set(5.97);
    . . . .
}

extends 상속 키워드를 사용하여 T가 Number클래스이거나 Number를 상속받지 않는 클래스일 경우 에러를 발생시킨다

제네릭 클래스의 타입 인자를 인터페이스로 제한하기

interface Eatable { public String eat(); } // abstract 생략됨

class Apple implements Eatable { // Apple 클래스가 Eatable 인터페이스를 구현함
    public String eat() {
    	return "It tastes so good!";
    }
    . . . .
}

class Box<T extends Eatable> {
    T ob;
    public void set(T o) { ob = o; }
    public T get() {
        System.out.println(ob.eat()); // Eatable로 제한하였기에 eat 호출 가능
        return ob;
    }
}

 

=> T extends Eatable의 의미는 제네릭을 설정해서 넘겨받는 타입이 되는 클래스가 Eatable 인터페이스를 구현하고 있지 않을 경우 타입에러 발생!!

하나의 클래스와 하나의 인터페이스에 대해 동시 제한

class Box<T extends Number & Eatable> {...}

인터페이스와 클래스를 동시에 지정할 수도 있다.

 

참조

https://seong-jun.tistory.com/entry/JAVA-The-type-parameter-T-should-not-be-bounded-by-the-final-type-Integer-Final-types-cannot-be-further-extended

 

[JAVA] The type parameter T should not be bounded by the final type Integer. Final types cannot be further extended

The type parameter T should not be bounded by the final type Integer. Final types cannot be further extended유형 매개변수 T는 최종 유형 Integer에 의해 제한되어서는 안 됩니다. 최종 유형은 더 이상 확장할

seong-jun.tistory.com

 

728x90
반응형
LIST