Programming/Java

[Java] 제네릭(Generic)을 예시를 통해 알아보자

cbw1030 2020. 10. 24. 10:49
반응형

안녕하세요. 이번 포스팅은 제네릭(Generic)입니다.

 

자바 과거 버전에서는 Object 자료형을 많이 사용했는데 이를 사용할 때 몇 가지의 문제점이 존재했습니다.

1. 형변환 문제

Object 자료형을 반환하고 목적에 맞는 자료형에 형변환을 할 때 실수하면 에러가 난다.

 

2. 목록에 아무나 들어갈 수 있는 문제

Object 자료형이기 때문에 어떠한 자료형을 넣어도 들어갈 수 있다.

 

3.  코드의 가독성 문제

Object 자료형을 형변환을 할 때 문장이 깔끔하지 않아 읽기의 어려움이 존재한다.

 

이러한 문제점들을 해결하기 위해 Object 자료형을 사용하기를 지양하면서 제네릭의 개념이 등장했습니다.

 

제네릭(Generic)이란?

제네릭은 컬렉션에서 많이 사용됩니다.

<String>, <Integer>, <String, Object>와 같은 < > 표현방식을 많이 보셨을 것입니다.

이 < > 안에 어떠한 타입을 선언해주어 List, Set, Map 등이 사용할 객체의 타입을 지정해줍니다.

< >에는 원시형은 올 수 없으며 래핑된 객체만이 들어갈 수 있습니다.

 

제네릭은 언제 사용할 수 있을까?

컬렉션의 Set으로 예를 들어보겠습니다.

Set set = new HashSet();

set.add("abc");
set.add(1);
set.add('a');

// forEach문
for (Object o : set)
    System.out.println(o);

위 예시의 출력값은 다음과 같습니다.

위 예시의 출력값

 

그런데 Set을 한 번쯤은 사용해 보신 분들은 'Set을 사용할 때 저렇게 사용했나?'라는 생각이 드실 수도 있습니다.

우선 Set 인터페이스를 들여다 보겠습니다.

Set 인터페이스
Collection 인터페이스

 

제네릭은 어떤 클래스나 인터페이스가 Generics를 이용해 구현이 되어있어야 합니다.

Set은 Collection 인터페이스를 구현하고 있고 Collection 인터페이스가 Generics를 지원합니다.

<E>로 되어 있는 것이 Generics를 지원한다는 의미입니다.

단, <E>에는 원시형이 아닌 래핑된 자료형을 넣어주어야 합니다.

 

제네릭을 사용하지 않고 Set set = new HashSet();을 했을 때 에러가 나지 않는 이유는 컴파일러가 자동으로 컴파일을 하는 과정에서 <Object>를 넣어주기 때문입니다.

그래서 forEach문에서 Obejct 형으로 받아 출력을 했던 것입니다.

 

코딩을 하다보면 자료형이 다른 데이터들을 ArrayList 또는 HashSet에 모아서 관리하는 일은 드뭅니다. 

그렇기 때문에 ArrayList 또는 HashSet을 사용할 때는 제네릭을 명시한 후에 사용하는 것이 좋습니다.

위의 예제에 제네릭을 적용해보겠습니다.

//Set<String> set = new HashSet<String>(); // 얘도 가능
Set<String> set = new HashSet<>();

set.add("aaa");
set.add("bbb");
set.add("ccc");

// forEach문
for (String o : set)
    System.out.println(o);

예제 출력값

Set에 String 자료형을 지정해주었기 때문에 set.add로 문자열밖에 추가를 할 수 없습니다.

ArrayList, HashMap 모두 마찬가지입니다.

 

다음 포스팅에서는 제네릭을 지원하는 클래스를 만들어 보도록 하겠습니다.

반응형