-
09. Generics멋사 부트캠프/Java 프로그래밍 2025. 3. 14. 16:57
1. Generics 란?
제네릭스(Generics)는 컴파일 시 타입을 체크하고, 다양한 데이터 타입을 처리할 수 있도록 도와주는 기능
- 와일드카드(Generics Wildcard) : 유연한 타입을 허용
- 기본형 와일드 카드 : List<?>
=> List<?> → "어떤 타입의 리스트인지 모르겠지만 받아들일 수 있음."
- 상한제한형 와일드 카드 : List<? extends T> T와 T의 하위클래스 허용
=> List<? extends Number> → Number 및 Integer, Double 등 가능
- 하한제한형 와일드 카드 : List<? super T> T와 T의 상위클래스 허용
=> List<? super Integer> → Integer, Number, Object 가능
😂😂😂
와일드 카드 사용예시)
---------------------------------------------------------------------------------------------
✅ ? → 타입이 정확히 필요하지 않고 모든 리스트를 받아야 할 때
✅ ? extends T → 읽기 전용, 리스트에서 값을 가져올 때 사용
✅ ? super T → 쓰기 전용, 리스트에 값을 추가할 때 사용
2. 제네릭스 활용 예제 및 사용 이유
1) 제네릭스를 사용하지 않은 클래스 경우 문제점
class Box { private Object value; public void setValue(Object value) { this.value = value; } public Object getValue() { return value; } } public class Main { public static void main(String[] args) { Box intBox = new Box(); intBox.setValue(10); Box strBox = new Box(); strBox.setValue("Hello"); // 형변환 필요 (타입 안정성 문제 발생 가능) int num = (Integer) intBox.getValue(); // ✅ 가능 String text = (String) strBox.getValue(); // ✅ 가능 } }
🚨 문제점: Object 타입이라 형변환이 필요하고, 잘못된 형변환 시 런타임 오류 발생 가능!
2) 제네릭스를 사용한 클래스 경우
class Box<T> { // "T"는 타입 파라미터 (임의의 타입을 지정 가능) private T value; public void setValue(T value) { this.value = value; } public T getValue() { return value; } } public class GenericExample { public static void main(String[] args) { Box<Integer> intBox = new Box<>(); // 정수형 박스 intBox.setValue(10); int num = intBox.getValue(); // 형변환 필요 없음! ✅ Box<String> strBox = new Box<>(); // 문자열 박스 strBox.setValue("Hello"); String text = strBox.getValue(); // 형변환 필요 없음! ✅ System.out.println(num); // 10 System.out.println(text); // Hello } }
✅ 타입을 유동적으로 변경하여 사용할 수 있다.
📌 제네릭 사용 이유!
✅ 제네릭은 타입 안전성을 높이고, 코드 중복을 줄이는 강력한 기능!
✅ 제네릭 클래스를 사용하면 타입 캐스팅이 필요 없음.
✅ 와일드카드(?)를 사용하면 제네릭을 더 유연하게 활용 가능!
3. 제네릭 메서드/인터페이스
1) 제네릭 메서드
class Util { // 제네릭 메서드 정의 public static <T> void printArray(T[] array) { for (T element : array) { System.out.print(element + " "); } System.out.println(); } } public class GenericMethodExample { public static void main(String[] args) { Integer[] intArray = {1, 2, 3}; String[] strArray = {"Hello", "World"}; Util.printArray(intArray); // ✅ 가능 (출력: 1 2 3) Util.printArray(strArray); // ✅ 가능 (출력: Hello World) } }
✅ 메서드에 T를 추가하여 다양한 타입을 받을 수 있도록 설정!
✅ 코드를 재사용할 수 있어 효율적!2) 제네릭 인터페이스
// 제네릭 인터페이스 정의 interface Calculator<T> { T add(T a, T b); } // Integer 타입 계산기 class IntegerCalculator implements Calculator<Integer> { public Integer add(Integer a, Integer b) { return a + b; } } // Double 타입 계산기 class DoubleCalculator implements Calculator<Double> { public Double add(Double a, Double b) { return a + b; } } public class GenericInterfaceExample { public static void main(String[] args) { Calculator<Integer> intCalc = new IntegerCalculator(); System.out.println(intCalc.add(5, 10)); // 15 Calculator<Double> doubleCalc = new DoubleCalculator(); System.out.println(doubleCalc.add(5.5, 2.2)); // 7.7 } }
✅ Calculator<T>를 사용해 다양한 타입의 계산기를 만들 수 있음!
🎯 제네릭 정리
제네릭 클래스 다양한 타입을 지원하는 클래스 class Box<T> { T value; } 제네릭 메서드 여러 타입을 지원하는 메서드 <T> void printArray(T[] array) 제네릭 인터페이스 타입에 따라 구현이 달라지는 인터페이스 interface Calculator<T> { T add(T a, T b); } 와일드카드 (?) 불특정한 타입을 표현 List<?> list ? extends T T의 하위 타입만 허용 (읽기 전용) List<? extends Number> ? super T T의 상위 타입만 허용 (쓰기 가능) List<? super Integer> '멋사 부트캠프 > Java 프로그래밍' 카테고리의 다른 글
11. 익명 클래스 & Functional 인터페이스 (0) 2025.03.14 10. Annotation (0) 2025.03.14 08. 예외 처리 (0) 2025.03.12 07. 추상 클래스 & 인터페이스 (0) 2025.03.11 06. 동적 바인딩 & 정적 바인딩 (0) 2025.03.11