ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 지네릭스(Generics)
    JAVA/지네릭스 2023. 8. 6. 15:39

    지네릭스란 다양한 타입의 겍체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다.

     

     

    class Box {
        Object item;
        
        void setItem(Object item) {
            this.item = item;
        }
        Object getItem() {
            return item;
        }
    }

    지네릭스를 사용하기 전에는 이렇게 Object로 변수들을 선언했다.

    ArrayList와 같은 컬렉션 클래스에서 다양한 종류의 객체를 담을 수 있긴 하지만 꺼낼 때마다 타입체크를 하고 형변환을 하는 것에 불편함이 있을 수 있다.

     

     

    지네릭 클래스로 변경

    class Box<T> {
        T item;
    
        void setItem(T item) {
            this.item = item;
        }
        T getItem() {
            return item;
        }
    }

    클래스 옆에 <T>를 붙이고 Object 타입을 모두 T로 바꿔주면 된다.

     

     

    public static void main(String[] args) {
        Box<String> b = new Box<String>();
        // Box<String> b = new Box<>(); 위의 코드와 동일 new Box<String>의 String은 생략 가능
        b.setItem("ABC");
        b.setItem(new Object()); // String 이외의 다른 타입은 에러
        String item = b.getItem();
    }

    생성자를 만들 때 Box<T>의 T 부분에 변수 타입을 지정해준다. 그러면 setItem에 변수를 넣을 때 지정한 변수 타입이 아니면 에러가 발생한다. 위의 예제에서는 String을 넣었기 때문에 b.setItem(new Object()) 부분에서 에러가 발생하게 된다.

    그리고 지네릭스를 사용하지 않았을 때에는 String item = (String) b.getItem(); 이라는 형변환이 필요했는데, 지네릭스를 사용할 때에는 별도의 형변환은 필요하지 않다.

     

     

    중요한 것은 Box<String>가 Box<Integer>는 같은 클래스를 다른 타입으로 호출한 것이므로 서로 다른 클래스를 호출한 것은 아니다. 마치 매개변수의 값이 다른 같은 클래스를 호출한 것과 비슷하다 볼 수 있다.

     

     

     

     

    public class Main {
        public static void main(String[] args) {
            Box<Food> foodBox = new Box<>();
            Box<Cake> cakeBox = new Box<>();
            // Box<Chicken> chickenBox = new Box<Cake>(); 같은 타입이 아니어서 에러
    
            foodBox.add(new Food());
            foodBox.add(new Chicken()); // Chicken이 food의 자손이라 가능
    
            cakeBox.add(new Cake());
            // cakeBox.add(new Food()); 자손 타입에 부모는 못 넣음
            // cakeBox.add(new Water()); 타입 불일치
    
            System.out.println(foodBox);
            System.out.println(cakeBox);
        }
    }
    
    class Food { public String toString() {return "Food";} }
    class Cake extends Food { public String toString() {return "Cake";} }
    class Chicken extends Food { public String toString() {return "Chicken";} }
    class Water { public String toString() {return "Water";} }
    
    class Box<T> {
        ArrayList<T> list = new ArrayList<>();
        void add (T item) {list.add(item);}
        T get (int i) {return list.get(i);}
        int size() {return list.size();}
        public String toString() {return list.toString();}
    }

    위와 같이 상속받는 경우에도 사용할 수 있고, 타입으로 ArrayList를 선언한 경우에는 그 타입이나 자손 타입만 들어올 수 있다.

Designed by Tistory.