728x90
반응형
Generic
- 제네릭에 대해 깊이 공부좀 해보자.
- 제네릭의 개념
- 제네릭의 타입
- 제네릭에서 경계와 제한 방법
- 제네릭 사용시 주의점
Generic 등장 배경
- Generic 의 등장 배경은 컬렉션으로 부터 시작이 된다.
- Generic 이 나오기전에는 컬렉션에서 객체를 꺼낼때 마다 형변환을 해야 했다.
- Java 5 부터 나온다
- Java 버전을 적은 이유는 raw 타입을 쓰지 말라고 해놓고 지원되는 이유다
- Java5 와 호환성을 위해 남겨두게 되었다.
형변환의 문제점
- 불편하다.
- 실수로 다른 타입을 넣게 되면 문제가 발생한다.
- 그것도 runtime 에!!!!!!!
Generic 이점
- 컴파일 시점에 타입을 체크한다.
- 컴파일이 안되니 런타임에 발생하는 문제를 없앨수 있다. - 위와 같은 이유로 안전성이 보장된다.
- 타입 검사를 코드에 넣을 필요가 없다.
Generic 의 타입
- T: 타입 보통 많이 사용한다. 하지만 코드를 보고 이해만 된다면
다른 걸로 사용해도 무방하다. - E: 요소 타입 보통 LIst<E> 이렇게 쓰인다.
- K, V: 보퉁 동시에 사용한다.
- K: Key 를 의미한다.
- V: Value 를 의미한다.
Generic 기본
- List 에서 Generic 을 사용하는 예이다.
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
Generic 용어 및 동작 과정
어떻게 변환 되는지 알아보자
- 변환전
public class VehicleRepairService<T> {
public boolean isSupport(T t) {
// 구현 필요
}
public void repair(T t){
// 구현 필요
}
}
- T 타입을 Vehicle 로 했을 경우
VehicleRepairService<Vehicle> = new VehicleRepairService<>()
public class VehicleRepairService { // 지네릭 타입을 Vehicle 로 했을 경우
public boolean isSupport(Vehicle t) {
// 구현 필요
}
public void repair(Vehicle t){
// 구현 필요
}
}
Generic 뜯어보기
- VehicleRepairService<T> 의 의미를 살펴보자.
VehicleRepairService<T> 지네릭 클래스 T 의 VehicleRepairService 또는 T VehicleRepairService 라고 읽는다.
T 타입 변수 또는 매개변수 .
VehicleRepairService 원시클래스
Generic 연습1
- 이동수단을 수리 하는 예제를 만들어 보자.
- Vehicle를 상속 받은 Car, Boat 를 수리하는 서비스를 만들어본다.
클래스 다이어 그램
- Vehicle 를 상속받아 Boat, Car 를 만든다.
Vehicle
@Getter
public class Vehicle {
private String engine;
private String type;
public Vehicle(String type, String engine) {
this.engine = engine;
this.type = type;
}
}
Car
package genric.base;
public class Car extends Vehicle {
public Car(String type) {
super(type, "careEngine");
}
}
Boat
package genric.base;
public class Boat extends Vehicle{
public Boat(String type) {
super(type,"boatEngine");
}
}
VehicleRepairService
- isSupport 가 왜 있는지 고민할 필요가 있다. 사실 지네릭을 통해 타입을 지정 해줬는데
왜 또 타입 검사를 할까? 이부분은 다음 예제에서 다루겠습니다.
public class VehicleRepairService<T> {
public boolean isSupport(T t) {
return (t instanceof Vehicle); // Vehicle 관련 인스턴스인지 확인
}
public void repair(T t){
if (isSupport(t)) { // Vehicle 관련 인스턴스면 수리
Vehicle vehicle = (Vehicle) t;
System.out.println(vehicle.getType() + " 수리완료");
} else {
System.out.println("수리불가");
}
}
}
테스트
- 추가로 house 클래스를 만들어서 실패하는 예제도 만들었다.
public class Test {
public static void main(String[] args) {
Boat boat = new Boat("기본 보트");
VehicleRepairService<Boat> boatVehicleRepairService = new VehicleRepairService<>();
boatVehicleRepairService.repair(boat);
Car car = new Car("기본 자동차");
VehicleRepairService<Car> carVehicleRepairService = new VehicleRepairService<>();
carVehicleRepairService.repair(car);
// 사실 House 타입이 올수가 없다.
House house = new House();
VehicleRepairService<House> vehicleRepairRepairService = new VehicleRepairService<>();
vehicleRepairRepairService.repair(house);
}
}
결과
기본 보트 수리완료
기본 자동차 수리완료
수리불가
정리
- 만약 Generic 이 없다면 RepairService 를 3개 만들어여 한다.
- Generic 을 사용함으로 써 하나의 서비스에서 여러개의 오브젝트를 다룰수 있다.
- 아래 처럼 타입 체크를 컴파일 단계에서 할수 있다.
문제점
- Generic 인데 타입검사를 내부에서 하고 있다.
이유는 어떠한 타입이든 지정할수 있기 때문이다. - 예제에서는 사실 House 는 들어올수가 없어야한다.
- 이러한 문제점을 제네릭의 제한에서 해결 할 수 있다.
다음으로
2022.06.21 - [Language/Java] - [Java] Generic 제한
실습 코드
https://github.com/rnrl1215/java-exercise/tree/main/src/main/java/generic
728x90
반응형
'Language > Java' 카테고리의 다른 글
[Java] Generic 와일드 카드 (0) | 2022.06.25 |
---|---|
[Java] Generic 제한 (0) | 2022.06.21 |
[Java] String to LocalDateTime (0) | 2022.02.12 |
[Java] Double의 제한사항 (0) | 2021.12.11 |
[Java] BigDecimal (2) | 2021.12.11 |
댓글