# 제네릭이 없다면?
1. 제네릭이 없는 상황
- 정수를 담는 `IntegerBox`와 문자열을 담는 `StringBox` 두 개의 클래스를 만들었다.
- 보관하고 꺼낼 수 있는 단순한 기능을 갖는다.
- 만약 `Double`, `Boolean`을 포함한 다양한 타입을 갖는 박스가 필요하다면
나는 각각의 타입별로 `Box`를 수십개 만들어야 할까? - 이 문제를 어떻게 해결하면 좋을까?
2. Object를 사용해서 해결
Object는 모든 타입의 부모이다. 다음 코드를 동작해보면 잘 동작되지만 2가지 부분이 걸린다.
public class ObjectBox {
private Object value;
public void set(Object object) {
this.value = object;
}
public Object get() {
return value;
}
}
public class BoxMain2 {
public static void main(String[] args) {
ObjectBox integerBox = new ObjectBox();
integerBox.set(10);
Integer integer = (Integer) integerBox.get(); //Object -> Integer 캐스팅
System.out.println("integer = " + integer);
ObjectBox stringBox = new ObjectBox();
stringBox.set("hello");
String str = (String) stringBox.get(); //Object -> String 캐스팅
System.out.println("str = " + str);
1) 잘못된 타입의 인수 전달 문제
실제로는 값을 넣는 개발자따로 꺼내는 개발자가 따로 있을 수도 있고 `IntegerBox.set("hello")` 와 같은 문자열이 보관된다면?...
값을 보관하는 `set()`의 매개변수 `Object` 이므로 값 입력에는 문제가 없다. 꺼낼 때 문제가 생긴다.
2) 반환 타입의 문제
`stringBox.get()`의 반환 타입은 Object이다.
자식은 부모를 담을 수 없어서 항상 사용할 때마다 다운 캐스팅을 해야한다.
처음에 비해 코드 재사용성 부분에선 좋아졌지만 위험한 다운 캐스팅을 계속 해야된다는 점에서 Object 사용도 그리 좋지 않아보인다.
# 제네릭 사용해보기
제네릭을 사용한다면 코드 재사용성과 안정성을 둘 다 챙길 수 있다.
1. 제네릭 - 예제
class Box<T> { // 제네릭 클래스 선언
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<String> stringBox = new Box<>();
stringBox.setValue("Hello");
String str = stringBox.getValue(); // 형 변환 필요 없음
Box<Integer> intBox = new Box<>();
intBox.setValue(10);
Integer num = intBox.getValue(); // 형 변환 필요 없음
}
}
2. 제네릭 - 특징
- <>를 사용한 클래스가 보인다.
- 제네릭 클래스를 사용할 때 `Integer`, `String`과 같은 타입을 미리 정하지 않는다.
- 제네릭은 기본 자료형은 사용할 수 없다. 대신 래퍼 클래스를 사용한다.
- 클래스 명 뒤에 `<T>`라고 있는데 이렇게 선언하면 제네릭 클래스가 된다. T는 타입 매개변수 라고 한다.
- 제네릭 클래스는 **생성하는 시점에 <> 사이에 원하는 타입을 지정**해서 사용한다.
- 정의하는 시점 ❌❌, 실제 사용하는 시점 ⭕⭕
- 원하는 모든 타입을 사용할 수 있다.
결정을 미래로 미루는 것이 바로 제네릭의 특징! 제네릭과 나의 공통점을 찾았다!
제네릭의 <타입> 매개변수와 <타입> 인자
제네릭 클래스를 정의할 때, 해당 클래스를 실제 사용하는 생성 시점에 타입을 결정하게 된다. 우리가 메소드에서 매개변수와 인자를 생각해보면 메소드는 매개변수에 인자를 전달해서 값을 결정한다.
그러면 제네릭은 타입 매개변수에 타입 인자를 전달해 사용 **타입**을 정한다.
제네릭은 값이 아니라 **타입**을 결정한다.
3. 제네릭 - 활용
'java' 카테고리의 다른 글
자바 - 계산기 과제 Lv3. 트러블슈팅(수정중) (1) | 2025.03.06 |
---|---|
자바 - 계산기 과제 Lv2. 트러블슈팅 (0) | 2025.03.05 |
자바 - 계산기 과제 Lv1. 트러블슈팅 (0) | 2025.03.01 |
자바 - 예외 처리 (0) | 2025.02.28 |