Java & Spring Boot

(Java) Generic 동작 원리 및 용도

Accept 2024. 2. 12. 22:37

 

해당 포스트는 JAVA의 Generic에 대한 동작 원리와 용도에 대한 내용을 포함하고 있습니다.

 

 

Java에서 제네릭(Generic)은 다양한 타입의 객체를 다루는 메소드나 컬렉션 클래스에 타입 체크와 타입 캐스팅을 컴파일 시간에 처리할 수 있게 도와주는 프로그래밍 기법입니다. 제네릭을 사용하면 코드의 재사용성을 높이고, 타입 안정성을 강화할 수 있습니다. 제네릭의 동작 원리와 용도에 대해 쉽게 설명해 보겠습니다.

 

동작 원리

제네릭을 사용하면 클래스, 인터페이스, 메소드를 정의할 때 타입(Type)을 파라미터로 사용할 수 있습니다. 이 타입 파라미터는 실제 클래스 타입이 사용될 때까지 구체적인 타입을 지정하지 않고, 코드 작성 시점에는 추상적인 '타입 변수'로서 사용됩니다. 컴파일 시, 컴파일러는 이 타입 변수를 사용하는 코드에 대해 적절한 타입 체크를 수행하여 타입 안정성을 보장하고, 필요한 타입 캐스팅을 자동으로 삽입합니다.

 

용도

1. 타입 안정성 강화 : 제네릭을 사용하면 컴파일 시점에 타입 체크가 이루어져, 실행 시간에 발생할 수 있는 `ClassCastException`과 같은 예외를 방지할 수 있습니다. 예를 들어, `List<String>`에는 문자열만 추가할 수 있으며, 다른 타입의 객체를 추가하려고 하면 컴파일 오류가 발생합니다.

2. 코드 재사용성 향상 : 제네릭을 사용하면 다양한 타입에 대해 동일한 코드를 재사용할 수 있습니다. 예를 들어, List<T>, Map<K, V> 등의 컬렉션은 제네릭을 사용하여 어떤 타입의 요소든지 저장하고 처리할 수 있는 범용성을 갖습니다.

  • T (Type) : 가장 일반적으로 사용되는 타입 변수로, 어떤 타입이든 될 수 있음을 의미합니다. 예를 들어, List<T>는 모든 타입의 리스트를 나타낼 수 있습니다.
  • K (Key) : 주로 맵(Map) 구조에서 키(Key)의 타입을 나타낼 때 사용됩니다. 예를 들어, Map<K, V>에서 K는 맵의 키 타입을 의미합니다.
  • V (Value) : 맵(Map) 구조에서 값(Value)의 타입을 나타낼 때 사용됩니다. 예를 들어, Map<K, V>에서 V는 맵의 값 타입을 의미합니다.
  • E (Element) : 컬렉션(Collection)에서 요소(Element)의 타입을 나타낼 때 사용되며, List<E>, Set<E> 등에서 볼 수 있습니다.
  • N (Number) : 숫자 타입을 나타낼 때 사용되기도 합니다. N은 Number 클래스의 하위 클래스일 수 있음을 의미합니다.


3. 명시적 타입 캐스팅 제거 : 제네릭을 사용하면 컬렉션에서 객체를 검색하거나 사용할 때 명시적으로 타입을 캐스팅할 필요가 없습니다. 컴파일러가 알아서 적절한 타입으로 처리해 줍니다.

 


예시

// 제네릭을 사용하지 않는 경우
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); // 명시적 타입 캐스팅 필요

// 제네릭을 사용하는 경우
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0); // 타입 캐스팅 불필요, 컴파일 시 타입 체크


제네릭을 사용하면 코드가 더 안전하고, 읽기 쉬우며, 유지보수하기 쉬워집니다. 타입 오류를 미리 잡아낼 수 있기 때문에 런타임에 발생할 수 있는 예외를 줄이고, 개발자가 보다 안정적인 코드를 작성할 수 있게 도와줍니다.

 

 

한마디로 정리하면

동작 원리 : 제네릭은 컴파일 시 타입을 체크하여 타입 안정성을 제공하고 타입 캐스팅을 줄여주는 프로그래밍 기법입니다.
용도 : 제네릭은 타입 안정성을 강화하며 코드의 재사용성을 높이기 위해 사용됩니다.