제네릭(Generics)
📌 제네릭(Generics)
: 일반화.
자바에서는 '자료형'이 그 대상임.
class Box<T> {
...
}
📌 제네릭(Generics) 사용 이유
: 저장된 인스턴스를 사용할 때 형 변환을 하는데, 이때 실수로 오류가 발생할 수 있으며, 그 실수가 드러나지 않을 수 있음. → 위 상황의 불편함을 줄이기 위해 제네릭(Generics)이 등장함.
→ 자료형에 의존적이지 않은 클래스 정의 가능해짐.
📌 자료형에 의존하지 않기 위해 Object 대신 T 사용.
T는 인스턴스 생성 시, 결정됨.
T의 역할을 알려주기 위해 클래스 이름 뒤에 <T> 붙임.
📌 용어
① 타입 매개변수(Type Parameter)
: Box<T>에서 T.
② 타입 인자(Type Argument)
: Box<Apple> boxA = new Box<Apple>( ); 에서 Apple.
③ 매개변수화 타입(Parameterized Type) = 제네릭 타입(Generic Type)
: Box<Apple>.
class Apple {
...
}
class Box<T> {
...
}
public class GenericsTest {
public static void main(String[] args) {
Box<Apple> boxA = new Box<Apple>();
...
}
}
📌 타입 매개변수 이름 규칙
① 한 문자.
② 대문자.
E | Element |
K | Key |
N | Number |
T | Type |
V | Value |
제네릭(Generics) - 에시
📌 제네릭(Generics) 예시
📄 GenericsTest.java
package generics;
class Apple {
public String toString() {
return "apple";
}
}
class Banana {
public String toString() {
return "banana";
}
}
class Box<T> { // 제네릭 기반의 클래스.
private T ob;
public void set(T o) {
ob = o;
}
public T get() {
return ob;
}
}
public class GenericsTest {
public static void main(String[] args) {
Box<Apple> boxA = new Box<Apple>();
Box<Banana> boxB = new Box<Banana>();
boxA.set(new Apple());
boxB.set(new Banana());
Apple a = boxA.get();
Banana b = boxB.get();
System.out.println(a.toString()); // apple
System.out.println(b.toString()); // banana
}
}
제네릭(Generics) - 매개변수화 타입
📌 매개변수화 타입을 구성할 때 기본 자료형을 타입 인자로 쓸 수 없음.
단, 기본 자료형에 대한 래퍼 클래스가 존재하고, 박싱과 언박싱이 자동으로 이루어지기 때문에
아래와 같은 코드 작성 가능.
📄 WrapperTest.java
package generics;
class Box<T> { // 제네릭 기반의 클래스.
private T ob;
public void set(T o) {
ob = o;
}
public T get() {
return ob;
}
}
public class WrapperTest {
public static void main(String[] args) {
// Box<int> box = new Box<int>(); // 타입 인자로 기본 자료형 사용 불가.
Box<Integer> box = new Box<Integer>();
box.set(10); // 오토 박싱.
int num = box.get(); // 오토 언박싱.
System.out.println(num); // 10
}
}
제네릭(Generics) - 타입 인자
📌 다이아몬드(Diamond) 기호
: 타입 인자 생략.
class Box<> {
...
}
📌 매개변수화 타입을 타입 인자로 사용 가능.
📄 BoxInBox.java
package generics;
class Box<T> { // 제네릭 기반의 클래스.
private T ob;
public void set(T o) {
ob = o;
}
public T get() {
return ob;
}
}
public class BoxInBox {
public static void main(String[] args) {
Box<String> b1 = new Box<>();
b1.set("Hello");
Box<Box<String>> b2 = new Box<>();
b2.set(b1);
Box<Box<Box<String>>> b3 = new Box<>();
b3.set(b2);
System.out.println(b3.get().get().get()); // Hello
}
}
📌 타입 인자 제한
: extends
① 클래스.
: 인스턴스 생성 시 설정한 클래스 또는 그 클래스를 상속하는 클래스만 타입 인자로 사용 가능.
class Box<T extends Number> {
...
}
② 인터페이스.
interface Sumable {
...
}
class Box<T extends Sumable> {
...
}
③ 클래스와 인터페이스 동시에 제한 가능.
interface Sumable {
...
}
class Box<T extends Number & Sumable> {
...
}
제네릭(Generics) 메소드
📌 제네릭(Generics) 메소드
: 제네릭(Generics)으로 정의된 메소드.
static 선언의 유무에 상관없이 정의 가능.
📌 static과 반환형 사이에 T가 타입 매개변수임을 알려야 함.
public static <T> Box<T> makeBox(T o) {
...
}
📌 메소드 호출 시 자료형이 결정됨.
📌 타입 매개변수 제한
: extends로 타입 매개변수 제한 가능.
제네릭(Generics) 인터페이스
📌 제네릭(Generics) 인터페이스
: 제네릭(Generics)으로 정의된 인터페이스.
제네릭(Generics) 상속
📌 제네릭(Generics) 클래스는 상속이 가능함.
'Java > Java' 카테고리의 다른 글
[Java] 컬렉션 프레임워크 - List<E> 인터페이스 (0) | 2022.10.18 |
---|---|
[Java] 와일드카드(Wildcard) (0) | 2022.10.18 |
[Java] Array 클래스 (0) | 2022.10.17 |
[Java] StringTokenizer 클래스 (0) | 2022.10.17 |
[Java] Math 클래스와 난수 생성 (0) | 2022.10.17 |
댓글