제네릭(Generic)이란?
제네릭은 다양한 타입의 데이터와 함께 사용할 수 있게 하는 클래스 및 메서드를 작성할 수 있게 해준다. 그래서 재사용성이 좋은 코드를 작성할 수 있게 해주고, 컴파일 과정에서 타입체크를 해주는 자바(5부터 도입)의 기능 중 하나이다.
다양한 타입의 데이터와 함께 사용할 수 있게 한다는 말이 이해가 잘 되지 않으니 예시 코드로 살펴보자.
public class Box<T> {
private T content;
public void put(T content) {
this.content = content;
}
public T get() {
return content;
}
}
Box라는 클래스를 <T> 타입으로 선언해주었다. 여기서 <T> 이 모양이 제네릭 표현식이다.
일반적으로 꺾쇠 모양 <> 안에 타입을 명시해준 형태가 제네릭이다.
현재 Box라는 클래스는 어떤 타입인지 정확히 명시되어 있지 않다. 한번 Box 객체를 생성해서 사용해 보자.
public class Generic {
public static void main(String[] args) {
Box<String> boxOfStrings = new Box<>();
boxOfStrings.put("parcel");
String content = boxOfStrings.get();
System.out.println("content = " + content); // content = parcel
Box<Integer> boxOfIntegers = new Box<>();
boxOfIntegers.put(10);
Integer number = boxOfIntegers.get();
System.out.println("number = " + number); // number = 10
}
}
첫 번째 Box는 String용 객체를 생성했고, 두 번째 Box는 Integer용 객체를 생성해서 각각 타입에 맞는 내용물을 저장해서 출력했다.
이렇게 제네릭은 하나의 Box 클래스로 두 개의 서로 다른 타입의 내용물을 저장할 수 있어 재사용이 가능한 코드를 작성할 수 있다는 장점이 있다.
제네릭의 장점으로 컴파일 시 타입을 체크해 주는 기능이 있다.
이 기능을 아래 예제 코드로 살펴보자.
우리는 제네릭을 ArrayList<Integer> 이 형태로 많이 접했을 텐데, 제네릭을 사용하지 않았을 때 코드를 살펴보자
public class Generic {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(10);
list.add(20);
list.add("10");
Integer number = (Integer) list.get(2);
System.out.println("number = " + number);
}
}
ArrayList에 Integer와 String을 담고 3번째 자리의 String 형태의 "10"을 꺼내서 Integer 형태로 변환한 다음 저장해도 컴파일 시에는 에러가 발생하지 않는다. 하지만 위 코드는 실행 시 형번환 에러가 발생한다. (컴파일러의 한계)
위 코드에서 제네릭을 사용해 ArrayList의 list에 Integr만 저장하겠다고 타입을 작성해 주어 컴파일 시 에러를 체크한다.
ArrayList<Integer> list = new ArrayList();
<Integer> 같이 ArrayList에 타입을 지정해 주면 Integer 이외의 타입을 저장하려고 하면 컴파일 에러가 발생한다.
실행 시 에러가 발생하는 것보다 컴파일 시에 에러가 발생하는 것이 개발 초기에 에러를 잡고 수정할 수 있기 때문에 개발 시간을 많이 절약할 수 있기 때문이다.
제네릭 사용 장점
1. 제네릭이 형식 안전성을 제공한다.
제네릭을 사용하면 코드가 올바른 유형의 데이터에서만 작동하는지 확인할 수 있다. 이렇게 하면 오류를 방지하고 코드를 더 안정적으로 만들 수 있다.
2. 제네릭을 사용해 코드의 재사용성을 높일 수 있다.
일반 클래스 및 메서드를 작성하면 모든 유형의 데이터에 사용할 수 있는 코드를 작성할 수 있습니다. 이렇게 하면 코드가 더 유연하고 재사용 가능해집니다.
3. 제네릭이 더 나은 성능을 제공한다.
제네릭을 사용하지 않으면 형변환 과정이 필요할 수 있는데 제네릭을 사용하면 형변환을 피할 수 있어 성능면에서 더 빠르고 효율적인 코드를 작성할 수 있다.
Reference
자바의 정석 ch12 - https://www.youtube.com/watch?v=QcXLiwZPnJQ
'Java' 카테고리의 다른 글
[Java] Type erasure 알아보기 (0) | 2023.03.11 |
---|---|
[Java] 리플렉션(Reflection)공부하기 (0) | 2023.03.01 |
[Java] Checked Exception과 Unchecked Exception (2) | 2023.02.27 |
[Java] Call By Reference와 Call By Value (0) | 2023.01.09 |
가비지 컬렉션(Garbage Collection)이란? (0) | 2023.01.03 |