작성한 클래스 또는 메서드의 타입을 지정하지 않고, 추후에 지정할 수 있도록 일반화해 두는 것
1. class Basket<T> { ... } // T: 타입 매개변수 (임의의 문자)
2. class Basket<K, V> { ... } // 여러개의 타입 매개변수 선언
🔍 모든 인스턴스가 공유하는 static 이 붙은 클래스 변수 또는 메서드에는 타입 매개변수 사용 불가!
Integer , Double ) 활용Basket<String> basket1 = new Basket<>("제네릭");
Basket<Integer> basket2 = new Basket<>(10);
Basket<Double> basket2 = new Basket<>(3.14);
// new Basket<타입> 생략 가능 (참조변수의 타입으로부터 유추)
class Flower { ... }
class Rose extends Flower { ... }
class RosePasta { ... }
class Basket<T> { ... }
class Main {
public static void main(String[] args) {
Basket<Flower> flowerBasket = new Basket<>(); // 제네릭 클래스 Basket의 타입 매개변수: Flower
flowerBasket.setItem(new Rose()); // 다형성 적용 (상속받고 있으므로)
flowerBasket.setItem(new RosePasta()); // 에러 (아무런 관계가 없으므로)
}
}
🧷 extends 키워드를 사용하여
class Basket<T extends Flower> { ... }
interface Plant { ... }
class Flower implements Plant { ... }
class Rose extends Flower implements Plant { ... }
** class Basket<T extends Plant> { ... }
class Main {
public static void main(String[] args) {
// 인스턴스화
Basket<Flower> flowerBasket = new Basket<>();
Basket<Rose> roseBasket = new Basket<>();
}
}
🧷 & 키워드를 사용하여
class Basket<T extends Flower & Plant> { ... }
클래스 내부의 특정 메서드만 제네릭으로 선언 가능
static 메서드에서도 선언하여 사용 가능class Basket<T> { // 1 : 여기에서 선언한 타입 매개 변수 T와
...
public <T> void add(T element) { // 2 : 여기에서 선언한 타입 매개 변수 T는 서로 다른 것
...
}
}
length()와 같은 String 클래스의 메서드는 제네릭 메서드를 정의하는 시점에 사용 불가equals(), toString() 등의 Object 클래스의 메서드는 사용 가능class Basket {
public <T> void print(T item) {
System.out.println(item.length()); // 불가
}
}
어떠한 타입으로든 대체될 수 있는 타입 파라미터, 기호 ? 로 사용 가능
// 일반적으로 extends와 super 키워드를 조합하여 범위를 지정해 사용
<? extends T> : 상한 제한, T와 T를 상속받는 하위 클래스 타입만 타입 파라미터로 받도록 지정
<? super T> : 하한 제한, T와 T의 상위 클래스만 타입 파라미터로 받도록 지정
<?> = <? extends Object> : 모든 클래스 타입을 타입 파라미터로 받을 수 있음