Java Mid 13 - Generic 2

제네릭 활용예제

package generic.test.ex3;

public class AnimalHospitalV2<T> {

    //다형성을 통한 중복제거
    private T animal;

    public void set(T animal) {
        this.animal = animal;
    }

    //T의 타입을 정의하는 시점에는 알 수가 없다. Object기능만 사용한다. -> Object는 모든 객체의 부모
    public void checkup() {

        animal.toString();
        animal.equals( null );

        /*System.out.println( "동물이름 : " + animal.getName() );
        System.out.println( "동물크기 : " + animal.getSize() );
        animal.sound()*/;

    }

    public T bigger(T target) {
/*
        return animal.getSize() > target.getSize() ? animal : target;
*/
        return null;
    }
}

T 를 사용해서 제네릭 타입을 선언했다.

제네릭 타입을 선언하면 자바 컴파일러 입장에서 T에 어떤 값이 들어올지 예측할 수 없다. 우리는 Animal 타입의 자식이 들어오기를 기대했지만, 여기 코드 어디에도 Animal에 대한 정보가 없다. (T타입 즉 제네릭으로 정의했기 때문에). T에는 타입 인자로 Integer가 들어올 수도 있고, Dog가 들어올 수도 있다.

물론 Object가 들어올 수도 있다.

package generic.test.ex3;

import generic.animal.Cat;
import generic.animal.Dog;

public class AnimalHostpitalMainV2 {
    public static void main(String[] args) {
        AnimalHospitalV2<Dog> dogHospital = new AnimalHospitalV2<>();
        AnimalHospitalV2<Cat> catHospital = new AnimalHospitalV2<>();
        AnimalHospitalV2<Integer> integerHospital = new AnimalHospitalV2<>();
        AnimalHospitalV2<Object> ObjectHospital = new AnimalHospitalV2<>();
        
    }
}

이 코드에서의 문제는?

  • 제네릭에서 타입 매개변수를 사용하면 어떠한 타입이든 들어올 수 있다.
  • 따라서 타입 매개변수를 어떤 타입이든 수용할 수 있는 Object로 가정하고, Object의 기능만 사용할 수 있다.
    • 발생한 문제들을 생각해보면 매개변수를 Animal로 제한하지 않았기 때문이다. 타입 인자가 모두 animal과 그 자식만 들어올 수 있게 제한한다면 어떨까?

타입 매개변수 제한

타입 매개변수를 특정 타입으로 제한할 수 있다.

package generic.test.ex3;

import generic.animal.Animal;

//T에 들어올 수 있는 것은 Animal 혹은 그 자식들만 들어올 수 있다.-> T는 animal의 자식들을 쓸 수 있다.
public class AnimalHospitalV3<T extends Animal> {

    private T animal;

    public void set(T animal) {
        this.animal = animal;
    }

    public void checkup() {
        System.out.println( "동물이름 : " + animal.getName() );
        System.out.println( "동물크기 : " + animal.getSize() );
        animal.sound();
    }

    public T bigger(T target) {
        return animal.getSize() > target.getSize() ? animal : target;
    }
}

  • 핵심은 이다.
  • 타입 매개변수 T를 animal과 그 자식만 받을 수 있도록 제한을 두는 것이다.
  • 즉 T의 상한이 Animal이 되는 것이다.

이렇게 되면 자바 컴파일러는 T에 입력할 수 있는 값의 범위를 예측할 수 있다.

Reference

인프런 김영한님의 자바강좌 + 나의 뇌



© 2022. by taewoo

Powered by taewoo