1️⃣ 제네릭(Generic)
- 제네릭은 클래스, 메서드 등에 사용되는
<T>**타입 매개변수**
를 의미합니다. - 타입을 미리 지정하지 않고 사용 시점에 유연하게 결정할 수 있는 문법입니다.
- 제네릭을 활용하면
코드 재사용성
과타입 안정성
을 보장받을 수 있습니다. - 하지만 과도하게 사용하면 오히려 복잡해질 수 있으므로 주의해야 합니다.
1. 코드 재사용성
- 다양한 타입에서 동일한 코드로 재사용이 가능합니다.
2. 타입 안정성
- 잘못된 타입 사용을 컴파일 시점에 방지합니다.
2️⃣ 제네릭이 없는 경우
1. 제네릭이 없는 클래스 - 재사용 불가
- 이 클래스는 특정 타입(
Integer
)으로 고정 되어 있어 재사용이 어렵습니다.String
타입 전용 박스가 필요하다면 다시 만들어야 합니다.
- 다시 사용하려면 다른 클래스를 만들어야 합니다.(낮은 유연성)
2. 제네릭이 없는 클래스 - 낮은 타입 안정성
- 다형성을 활용하면 다양한 타입을 저장 가능하지만 실행 중 오류가 발생할 가능성이 높습니다.
- 사용 시 형 변환이 필요하고 실수로 잘못된 타입을 사용하면 런타임 오류가 발생합니다.
→ 잘못된 다운케스팅 활용 시:ClassCastException
3️⃣ 제네릭 활용(재사용성 + 타입안정성)
✅ 제네릭 <T>
(타입매개변수)
<T>
(타입매개변수) 는 제네릭에서 타입을 의미하는 자리입니다.- 실제 데이터 타입으로 대체되어 활용 됩니다.
✅ 클래스에 제네릭을 활용해 재사용성과 타입안정성을 보장받을 수 있습니다.
제네릭 클래스
는 클래스 선언부에<T>
가 선언된 클래스입니다.제네릭 클래스
는 클래스 선언시 타입 매개변수를 사용해 다양한 데이터 타입을 안전하게 처리할 수 있는 구조입니다.GenericBox<T>
를 활용해서String
,Integer
,Double
등 다양한 타입 저장 가능 합니다.
public class GenericBox<T> { // ✅ 제네릭 클래스
private T item;
public GenericBox(T item) {
this.item = item;
}
public T getItem() {
return this.item;
}
}
✅ 타입소거(Erasure)
- 타입 소거는 컴파일 시점에 제네릭 타입 정보를 제거하는 과정입니다.
<T>
타입 매개변수 부분은Object
로 대체됩니다.- 필요한 경우 컴파일러가 자동으로 강제 다운 캐스팅(cast) 코드를 삽입하여 타입 안전성을 보장합니다.
public class Main {
public static void main(String[] args) {
// 1. ✅ 재사용 가능(컴파일시 타입소거: T -> Object)
GenericBox<String> strGBox = new GenericBox<>("ABC");
GenericBox<Integer> intGBox = new GenericBox<>(100);
GenericBox<Double> doubleGBox = new GenericBox<>(0.1);
// 2. ✅ 타입 안정성 보장(컴파일시 타입소거: 자동으로 다운캐스팅)
String strGBoxItem = strGBox.getItem();
Integer intGBoxItem = intGBox.getItem();
Double doubleGBoxItem = doubleGBox.getItem();
System.out.println("strGBoxItem = " + strGBoxItem);
System.out.println("intGBoxItem = " + intGBoxItem);
System.out.println("doubleGBoxItem = " + doubleGBoxItem);
}
}
4️⃣ 제네릭 메서드(Generic Method)
- 제네릭 메서드
는 메서드 내부에서 사용할 타입을 유연하게 지정하는 기능입니다.
- 제네릭 메서드는 메서드 선언부에
<T>
가 선언된 메서드입니다. - 제네릭 메서드는 클래스 제네릭 타입과 별개로 독립적인 타입 매개변수를 가집니다.
→ 타입 소거 과정을 생각해 보세요.
public class GenericBox<T> {
// 속성
private T item;
// 생성자
public GenericBox(T item) {
this.item = item;
}
// 기능
public T getItem() {
return this.item;
}
// ⚠️ 일반 메서드 T item 는 클래스의 <T> 를 따라갑니다.
public void printItem(T item) {
System.out.println(item);
}
// ✅ 제네릭 메서드 <S> 는 <T> 와 별개로 독립적이다.
public <S> void printBoxItem(S item) {
System.out.println(item);
}
}
public class Main {
public static void main(String[] args) {
GenericBox<String> strGBox = new GenericBox<>("ABC");
GenericBox<Integer> intGBox = new GenericBox<>(100);
// ⚠️ 일반메서드: 클래스 타입 매개변수를 따라갑니다.
// String 데이터 타입 기반으로 타입소거가 발생.
// String 타입의 다운캐스팅 코드 삽입!
strGBox.printItem("ABC"); // ✅ String 만 사용가능
strGBox.printItem(100); // ❌ 에러 발생
// ✅ 제네릭 메서드: 독립적인 타입 매개변수를 가집니다.
// String 타입 정보가 제네릭 메서드에 아무런 영향을 주지 못함.
// 다운캐스팅 코드 삽입되지 않음.
strGBox.printBoxItem("ABC"); //✅ 모든 데이터 타입 활용 가능
strGBox.printBoxItem(100); //✅ 모든 데이터 타입 활용 가능
strGBox.printBoxItem(0.1); //✅ 모든 데이터 타입 활용 가능
}
}
5️⃣ 제네릭이 활용된 곳
✅ 자바에서 <T>
제네릭이 활용된 곳
Optional<T>
와ArrayList<T>
컬렉션 클래스 등은 제네릭 클래스입니다.- 여기서
<T>
는 실제 데이터 타입으로 대체되어 활용됩니다.
'코딩 공부 > Java' 카테고리의 다른 글
[Java]개행문자 입력 처리 (0) | 2025.02.27 |
---|---|
[Java] Chpater 3 - 05) 람다(Lambda) (0) | 2025.02.26 |
[Java] Chpater 3 - 03) 컬렉션(Collection) (0) | 2025.02.26 |
[Java] Chpater 3 - 02) Optional - null 을 다루는 법 (0) | 2025.02.26 |
[Java] Chpater 3 - 01) 예외(Exception)과 예외처리(try-catch) (0) | 2025.02.26 |