-
지네릭스(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를 선언한 경우에는 그 타입이나 자손 타입만 들어올 수 있다.