본문 바로가기
Java, JSP

[Java/자바] Generic, 제네릭

by LasBe 2022. 1. 8.
반응형

제네릭이란

프로그램에서 변수와, 메소드를 선언할 때 자료형을 선언해줍니다.

 

대부분 하나의 자료형으로 구현되지만, 변수나 메소드의 자료형을 필요에 따라

여러 자료형으로 사용할 수 있다면 프로그램을 유연하게 사용할 수 있을 겁니다.

 

이와 같이 어떤 값이 하나의 참조 자료형이 아닌

여러 참조형을 사용할 수 있도록 프로그래밍하는 것을 제네릭(generic)이라고 합니다.

 

제네릭은 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시, 미리 지정하는 방법입니다.

 

제네릭을 사용하면 참조 자료형이 변환될 때 이에 대한 검증을 컴파일러가 하므로 아래와 같은 장점이 있습니다.

  • 클래스와 메소드 내부 객체의 타입 안정성을 높임
  • 반환 값에 대한 타입 변환 및 타입 검사에 들어가는 노력이 줄어듦

그럼 코드를 통해 자세한 사용법을 알아보겠습니다.

 

 

제네릭 정의와 선언

일반적인 클래스와 같이 정의하지만 클래스명 뒤에 <>(다이아몬드 연산자)가 있는 것을 확인할 수 있습니다.

class 클래스명<T>{ ... }
// T는 자료형의 타입

이는 자료형의 타입을 나타내는 타입 파라미터로 아래와 같이 다양한 파라미터를 사용할 수 있습니다.

타입 파라미터 설명
<T> Type
<E> Element
<K> Key
<N> Number
<V> Value
<R> Result

 

그러면 클래스를 더 구체화해보겠습니다.

class GenericClass<T>{ // T는 자료형의 타입
	private T var;
	
	public void set(T t) {
		var = t;
	}
	
	public T get() {
		return var;
	}
}

set은 타입별로 파라미터를 받아 변수에 저장해주고 get은 변수를 리턴해주는 메소드입니다.

 

그러면 아래 코드에서 선언과 동시에 어떻게 사용하는지 확인해보겠습니다.

public class GenericEx {
	public static void main(String[] args) {
		GenericClass<String> genStr = new GenericClass<>(); // String으로 선언
		genStr.set("hello world");
		System.out.println("String 타입의 변수 : "+ genStr.get());
		
		GenericClass<Integer> genInt = new GenericClass<>(); // Integer로 선언
		genInt.set(100);
		System.out.println("Integer 타입의 변수 : "+genInt.get());
	}
}

매개변수의 타입에 String과 Integer를 넣어도 둘 다 실행이 잘 되는 것을 볼 수 있습니다.

 

왜 타입에 string과 int를 넣지 않았을까요?

 

그 이유는 제네릭에서는 선언할 수 있는 타입이 객체 타입이기 때문입니다.

 

int나 string은 기본자료형이기 때문에 제네릭의 타입으로 사용할 수 없습니다.

 

 

그럼 제네릭을 사용하지 않았을 때 어떤 불편함이 있는지 아래 코드로 알아보겠습니다.

class NonGenericClass{
	private Object var;
	
	public void set(Object o) {
		var = o;
	}
	public Object get() {
		return var;
	}
}

클래스의 구성은 제네릭을 사용했을 때와 같지만 타입 파라미터를 받는 대신

최상위 클래스인 Object로 변수를 지정해주고 리턴하는 것을 볼 수 있습니다.

 

선언부에서 제네릭 없이 선언하게 되면 아래와 같이 데이터를 주고받음에 있어 형 변환이 필요하게 됩니다.

public class NonGeneric {
	public static void main(String[] args) {
		NonGenericClass ng = new NonGenericClass();
		String str = "hello world";
		
		ng.set(str); // 서브 클래스(String) -> 슈퍼 클래스(Object) = 자동 형변환
		
        	// 슈퍼 클래스(Object) -> 서브 클래스(String) = 직접 형변환을 해주어야 함
		String str2 = (String)ng.get(); 
	}
}

이와 같이 자식 클래스에서 데이터를 꺼내올 때는 원래의 타입으로 형 변환이 필요하게 되지만

제네릭 같은 경우 선언할 때 타입을 지정해주면 그 타입의 객체만 사용할 수 있음으로 별도의 형 변환이 필요 없게 됩니다.

 

이로써 타입 체크와 형 변환을 생략할 수 있으므로 코드가 간결해지고 성능의 향상을 기대할 수 있습니다.

 

더보기
더보기

자바 제네릭, java generic, arraylist, 형 변환, 자바 형 변환, 

반응형

댓글


오픈 채팅