[JAVA] 지네릭스
2020. 7. 7. 20:24ㆍ기본 문법/[JAVA]
지네릭스를 왜 쓸까?
먼저 우리는 지네릭스를 쓰지 않는 경우를 생각해보자.
class Box{
Object item;
Box(Object item){
this.item = item;
}
Object getItem() {
return item;
}
}
public static void main(String[] args) {
Box box = new Box("asdfxzcv");
// String temp = box.getItem(); // 에러가 날 것이다.
String temp = (String) box.getItem(); // 형변환을 해주고 타입체크를 해줘야댐
}
먼저 Object는 최상위 클래스이다. 그렇기 때문에 생성자를 통해서 String이나 int로 item을 만들어도 에러가 나지 않을 것이다. 하지만 저장된 객체를 꺼내올 때 우리가 잠시 객체를 받도록 해보면 지네릭스를 쓸 때와 쓰지 않을 때의 차이점을 알 수 있다.
먼저 위의 코드를 지네릭스로 써보자.
class Box<T>{
T item;
Box(T item){
this.item = item;
}
T getItem() {
return item;
}
}
public static void main(String[] args) throws IOException {
Box<String> box = new Box("asdfxzcv");
String temp = box.getItem();
}
지네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능을 한다.
지네릭스는 컴파일 후에 지네릭스 타입이 제거된다.
이 말은 Box<String>이나 Box<Integer>를 하고 나서
모두 타입 변수인 String이나 Integer이 아닌 '원시 타입'인 Box로 바뀐다는 것이다.
지네릭스의 장점
- 타입 안정성을 제공한다.
- 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해진다.
지네릭스 제한
- 모든 객체에 대해 동일하게 동작해야하는 static멤버에 타입변수 T를 사용할 수 없다.
T는 인스턴스 변수로 간주되기 때문이다. (static 멤버는 인스턴스 변수를 참조할 수 없다.) - 지네릭 배열 타입의 참조변수를 선언하는 것은 가능하다.
- new T[10] 같이 배열을 생성하는 건 안된다. new 연산자는 컴파일 시점에 타입 T가 무엇인지 정확히 알아야 한다.
- 지네릭 배열이 필요할 경우에는 new 연산자 대신 newInstance()와 같이 동적으로 객체를 생성하는 메서드로 배열을 생성하거나, Object배열을 생성해서 복사한 다음에 'T[]'로 형변환하는 방법을 사용한다.
- 더 자세하게 알고 싶다면 여기를 눌러 참조하자.
- instanceof 연산자도 같은 이유로 T를 피연산자로 사용할 수 없다.
제한된 지네릭 클래스
지네릭 타입에 extends를 사용하면, 특정 타입의 자손들만 대입할 수 있게 제한할 수 있다.
class Animals<T extends Animal> { //Animal의 자손만 타입으로 지정 가능
}
인터페이스를 구현해야 한다는 제약이 필요하다면, 이때도 implements 대신 extends를 사용한다.
interface Working {}
class Animals<T extends Working> {
}
클래스 Animal의 자손이면서 Working 인터페이스도 구현해야하면 & 기호로 연결한다.
class Animals<T extends Animal & Working>{
}
'기본 문법 > [JAVA]' 카테고리의 다른 글
[JAVA] 정규식 표현 (0) | 2021.09.25 |
---|---|
[JAVA] Stream (0) | 2020.10.28 |
[JAVA] Set - TreeSet (0) | 2020.06.16 |
[JAVA] Set - HashSet (0) | 2020.06.14 |
[JAVA] Iterator (0) | 2020.06.14 |