Java 제네릭(Generics)

Generics란?

제네릭스(Generics)는 Java5에서 도입된 것으로, 데이터형을 일반화 한다(Generalize) 라는 의미이다.
제네릭스는 클래스 또는 메소드에서 사용하는 데이터형을 미리 지정하는 방법이다.
제네릭스를 사용하면 데이터 형식 불일치 문제를 컴파일 과정에서 예방할 수 있다.
그리고 제네릭스를 사용하면 형 캐스트를 할 필요가 없어져 프로그램의 성능이 향상된다.

BadGenericsSample.java

package com.devkuma.basic.generics; import java.util.ArrayList; import java.util.List; public class BadGenericsSample { public static void main(String[] args) { List arrayList = new ArrayList(); arrayList.add("test"); String test = arrayList.get(0); // error } }

위의 예제과 같이 제네릭으로 데이터 유형을 지정하지 않고, 데이터를 저장하게 되면 저장할 데이터는 Object 형식으로 저장된다. 그래서 가져올 시에는 형변환를 반듯시 해야 한다.

GoodGenericsSample.java

import java.util.ArrayList; import java.util.List; public class GoodGenericsSample { public static void main(String[] args) { List<String> arrayList = new ArrayList(); arrayList.add("test"); String test = arrayList.get(0); // ok } }

제네릭으로 데이터형을 미리 지정하면 저장되는 데이터가 지정된 데이터로 저장되므로, 데이터를 가져올 시에는 형변환을 하지 않아도 된다.

제네릭스를 쓰는 법

제네릭스은 아래와 같이 선언한다.

public class 클래스명<T> public interface 인터페이스명<E>

<>괄호 안에는 정해진 규칙은 없지만, 일반적으로 대문자와 알파벳으로 표현한다.

클래스에 제네릭 사용

아래는 클래스에 제레릭을 사용한 예제이다.

package com.devkuma.basic.generics.ex2; public class GenericsSampleClass<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }

위와 같이 작성한 클래스는 인스턴스를 생성해 사용할 때, 데이터 형식을 지정하여 사용한다.

package com.devkuma.basic.generics.ex2; public class GenericsSample { public static void main(String[] args) { GenericsSampleClass<String> classSample = new GenericsSampleClass(); classSample.setT("SetItem"); String getItem = classSample.getT(); } }

인터페이스에 제네릭 사용

아래는 인터페이스에 제레릭을 사용한 예제이다.

package com.devkuma.basic.generics.ex3; public interface GenericInterfaceSample<T> { T testMethod(T t); }

위와 같이 작성된 인터페이스는 구현 클래스에서 데이터형을 지정할 수 있다.

package com.devkuma.basic.generics.ex3; public class GenericInterfaceSampleImpl implements GenericInterfaceSample<String> { @Override public String testMethod(String t) { return null; } }

제네릭스의 범위 지정

제네릭으로 지정하는 데이터형의 범위도 상속을 이용하면 제한할 수 있다.

package com.devkuma.basic.generics.ex4; public class GenericClassSample<T extends Number>{ private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }

위와 같이 작성되고 있는 클래스는 제네릭스로 데이터형을 지정할 때, Number 클래스를 상속하는 클래스만 지정할 수 있다.

package com.devkuma.basic.generics.ex4; public class GenericSample { public static void main(String[] args) { GenericClassSample<String> classSample = new GenericClassSample(); // error classSample.setT("SetItem"); String getItem = classSample.getT(); } }

위와 같이 제네릭로 데이터형을 String을 지정하였지만, StringNumber 클래스의 하위 클래스가 아니기 때문에 컴파일 에러가 발생한다.

최종 수정 : 2022-04-03