Free Lines Arrow
본문 바로가기
Language/Java

[Java] Generic 기초

by skahn1215 2022. 6. 11.
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 제한

 

[Java] Generic 제한

Generic 제한 제네릭의 접근 제한에 대해 알아본다. 앞서 Generic 기초에서 모든 타입을 받을수 있다는 것을 알았다. 하지만 타입을 제한 해야 되는 일이 필요하다면? Generic 제한 필요성 Generic 기초에

vprog1215.tistory.com

 

 

실습 코드

https://github.com/rnrl1215/java-exercise/tree/main/src/main/java/generic

 

GitHub - rnrl1215/java-exercise

Contribute to rnrl1215/java-exercise development by creating an account on GitHub.

github.com

 

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

댓글