재네릭(Generic)
재네릭은 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움을 줄일 수 있다.
타입 안정성을 높인다는 것은 의도하지 않은 타입의 객체가 저장되는 것을 막고, 저장된 객체를 꺼내올 때 원래의 타입과 다른 타입으로 잘못 형변환되어 발생할 수 있는 오류를 줄여준다는 뜻이다.
재네릭의 장점
1. 타입 안정성을 제공한다.
2. 타입체크와 형변환을 생략할 수 있어 코드가 간결해 진다.
재네릭 이전의 코드
재네릭 이전의 코드에 대해서 살펴보자.
먼저 무엇이든 저장하고 꺼낼 수 있는 상자를 준비해 준다.
class Apple{
public String toString() {
return "I am an apple.";
}
}
class Orange{
public String toString() {
return "I am an orange.";
}
}
class Box{ //무엇이든 저장하고 꺼낼 수 있는 상자
private Object ob;
public void set(Object o) {
ob = o;
}
public Object get() {
return ob;
}
}
각각의 상자에 사과와 오렌지를 담았지만 실제 이 상자들은 object 형을 참조하기 때문에 명시적인 형변환을 필요로 한다. 그리고 이것은 컴파일러의 오류 발견 가능성을 낮추는 결과로 이어진다. (코드의 안정성이 떨어짐)
public class Main {
public static void main(String[] args){
Box aBox = new Box(); // 상자 생성
Box oBox = new Box(); // 상자 생성
aBox.set(new Apple()); // 상자에 사과를 담는다.
oBox.set(new Orange()); // 상자에 오렌지를 담는다.
Apple ap = (Apple)aBox.get(); // 상자에서 사과를 꺼낸다.
Orange og = (Orange)oBox.get(); // 상자에서 오렌지를 꺼낸다.
System.out.println(ap);
System.out.println(og);
}
}
더욱더 큰 문제는 아래처럼 꺼내는 과정에서 바로 println 메서드를 호출했을 때 어떠한 오류도 발생하지 않기 때문에 프로그래머가 자신이 무엇을 실수했는지 조차 알수없다는 것이다.
public class Main {
public static void main(String[] args){
Box aBox = new Box();
Box oBox = new Box();
//프로그래머의 실수
//사과와 오렌지가 아닌 문자열을 담았다
aBox.set("Apple");
oBox.set("Orange");
System.out.println(aBox.get()); // Apple
System.out.println(oBox.get()); // Orange
}
}
재네릭 이후의 코드
Box 클래스를 재네릭화 시켜보겠다.
아래의 의미는 인스턴스 생성시에 T의 값을 필요에 맞게 결정하겠다는 의미이다.
class Box<T>{
private T ob;
public void set(T o) {
ob = o;
}
public T get() {
return ob;
}
}
이와 같이 타입을 미리 지정해 주었기 때문에 상자에 다른 타입의 물건을 담으려 할 때 에러가 발생한다.
이렇게 재네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있고 따로 타입을 체크하고 변화해 줄 필요가 없다.
public static void main(String[] args){
Box<Apple> aBox = new Box<Apple>();
// T를 Apple로 결정하여 인스턴스 생성
// 따라서 Apple 또는 Apple을 상속하는 하위 클래스의 인스턴스 저장가능
Box<Orange> oBox = new Box<Orange>();
// T를 Orange로 결정하여 인스턴스 생성
// 따라서 Orange 또는 Orange을 상속하는 하위 클래스의 인스턴스 저장가능
aBox.set(new Apple()); // 상자에 사과를 담는다.
oBox.set(new Orange()); // 상자에 오렌지를 담는다.
//aBox.set("Apple"); // 에러방생
//oBox.set("Orange"); // 에러발생
Apple ap = aBox.get(); // 사과를 꺼내는데 형 변환 하지 않는다.
Orange og = oBox.get(); // 오렌지를 꺼내는데 형 변환 하지 않는다.
System.out.println(ap);
System.out.println(og);
}'Language > Java' 카테고리의 다른 글
| [Java] 객체지향프로그래밍(OOP)란? (0) | 2022.09.15 |
|---|---|
| [Java] 형변환(캐스팅, casting) (0) | 2022.09.14 |
| [Java] 자바의 명명규칙 (0) | 2022.09.13 |
| [Java] JVM 메모리 구조 (0) | 2022.09.12 |
| [Java] Queue(큐) 클래스 정리 (0) | 2022.09.08 |