코린이의 소소한 공부노트

지네릭 클래스의 예시와 제한 본문

Java

지네릭 클래스의 예시와 제한

무지맘 2022. 11. 14. 13:46

[Iterator<E>]

- 클래스를 작성할 때 Object타입 대신 T와 같은 타입 변수를 사용한다.

// 일반 클래스				// 지네릭 클래스
public interface Iterator{		public interface Iterator<E>{
    boolean hasNext();				boolean hasNext();
    Object next();				E next();
    void remove();				void remove();
}					}
// 생성 및 사용
Iterator it = list.iterator();		Iterator<Student> it = list.iterator();
while(it.hasNext()){			while(it.hasNext()){
    Student s = (Student)it.next();		Student s = it.next();
    // 타입 불일치로 인한 형변환 필요		// 타입이 일치하므로 형변환 필요X
    ...						...
}					}


[HashMap<K,V>]

- 여러 개의 타입 변수가 필요한 경우, 콤마(,)를 구분자로 해서 선언하면 된다.

public class HashMap<K,V> extends AbstractMap<K,V> ... {
    ...
    public V get(Object key) { }
    public V put(K key, V value) { }
    public V remove(Object key) { }
    ...
    // get()과 remove()의 매개변수 타입을 그대로 Object로 두는 이유는
    // 메서드 내부에서 hash(Object o)를 이용하기 때문에 굳이 바꿔줄 필요가 없다.
}
// 생성 및 사용
HashMap<String, Student> map = new HashMap<>(); // 생성자쪽 지네릭타입 생략 가능
// Student(String name, int ban, int no, int kor, int eng, int math)
map.put("무지", new Student("무지", 1, 1, 100, 100, 100));
// public Student get(Object key)
Student s = map.get("무지");
System.out.println(s.math); // 100

 

[제한된 지네릭 클래스]

1. 지네릭 타입에 ‘extends’를 사용하면, 특정 타입의 자손들만 대입할 수 있게 제한할 수 있다.

class FruitBox<T extends Fruit>{ // Fruit의 자손만 타입으로 지정 가능
    ArrayList<T> list = new Arraylist<T>();
    void add(T item) { list.add(item); }
    ...
}

FruitBox<Fruit> fruitBox = new FruitBox<Fruit>(); // OK
FruitBox<Apple> appleBox = new FruitBox<Apple>(); // OK
FruitBox<Toy> toyBox = new FruitBox<Toy>(); // 에러. Toy는 Fruit의 자손이 아님

// add()의 매개변수의 타입 T도 Fruit와 그 자손 타입이 될 수 있다.
fruitBox.add(new Apple()); // OK. Apple이 Fruit의 자손
fruitBox.add(new Toy()); // 에러. Toy는 Fruit의 자손이 아님

 

2. 인터페이스의 경우에도 ‘implements’가 아닌, ‘extends’를 사용한다.

interface Eatable { }
class FruitBox<T extends Eatable> { }
class FruitBox<T extends Fruit & Eatable> extends Box<T> { } // , 대신 &를 사용

 

[지네릭스의 제약]

1. static 멤버에는 타입 변수를 사용할 수 없다.

// 타입 변수에 대입하는 것은 인스턴스 별로 다르게 할 수 있다.
Box<Apple> appleBox = new Box<Apple>(); // OK. Apple객체만 저장 가능
Box<Grape> grapeBox = new Box<Grape>(); // OK. Grape객체만 저장 가능

// static은 모든 인스턴스에 공통으로 사용되기 때문에 타입 변수를 사용할 수 없다.
class Box<T>{
    static T item; // 에러
    static int compare(T t1, T t2) { } // 에러
    ...
}

2. 지네릭 타입의 배열 T[]를 생성하는 것은 허용되지 않는다. 타입 변수로 배열 선언은 가능하다.

T[] itemArr; // OK. T타입의 배열을 위한 참조변수 선언은 가능
T[] toArray() {
    T[] tmpArr = new T[itemArr.length]; // 에러. 지네릭 배열은 생성 불가
    // new 키워드 뒤에는 확정된 타입이 와야하기 때문이다.
    ...
    return tmpArr;
}

 

 

'Java' 카테고리의 다른 글

지네릭 타입의 형변환과 제거  (0) 2022.11.14
와일드카드 ?와 지네릭 메서드  (0) 2022.11.14
지네릭스와 다형성  (0) 2022.11.09
지네릭스  (0) 2022.11.09
Collections 클래스  (0) 2022.11.08