본문 바로가기
자바 한계단

제네릭 Generic

by juneMiller 2022. 1. 27.

제네릭을 사용해야 하는 이유 

 

제네릭타입을 사용하므로서 잘못된 타입이 사용될 수 있는 문제를 

컴파일 과정에서 제거 할 수 있기 때문에 사용한다.

 

ArrayList list = new ArrayList(); //제네릭을 사용하지 않을경우
list.add("test");
String temp = (String) list.get(0); //타입변환이 필요함
        
ArrayList<String> list2 = new ArrayList(); //제네릭을 사용할 경우
list2.add("test");
temp = list2.get(0); //타입변환이 필요없음

 

 

제네릭 사용법 

제네릭 타입은 타입을 피라미터로 가지는 클래스와 인터페이스를 말합니다. 

제네릭 타입은 클래스 또는 인터페이스 이름 뒤이 <>부호가 붙고 사이에 타입 피라미터가 위치 한다. 

 

public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}

 

<T>  type 

<E> Element

<K> Key

<N> Number

<V> Value

<R> Result 

 

 

 

제네릭 클래스 만들기 

package practice;

public class ExClassGeneric<T> {

	private T t;
	
	public void setT(T t) {
		this.t = t;
	}
	
	public T getT() {
		return t; 
	}
}

 

위와 같이 클래스를 설계할 때 구체적인 타입을 명시하지 않고 타입 파라미터로 넣어두었다가 

실제 설계한 클래스가 사용되어질 때, ExClassGeneric<String> exGeneric = new ExClassGeneric<>();

이런식으로 구체적인 타입을 지정하면서 사용하면 타입 변환을 최소화 시킬 수 있습니다. 

 

 

 

제네릭 인터페이스

 

public interface ExInterfaceGeneric<T> {
	T example();
}

class ExGeneric implements ExInterfaceGeneric<String> {

	@Override
	public String example() {
		// TODO Auto-generated method stub
		return null;
	}
	
}

인터페이스도 위와 같이 클래스처럼 제네릭으로 설정해두고 활용할 수 있습니다. 

 

 

 

 

멀티 타입 피라미터 사용

 

package practice;

import java.util.Map;

public class ExMultiTypeGeneric<K, V> implements Map.Entry<K, V>{

	private K key;
	private V value;
	@Override
	public K getKey() {
		// TODO Auto-generated method stub
		return this.key;
	}
	@Override
	public V getValue() {
		// TODO Auto-generated method stub
		return this.value;
	}
	@Override
	public V setValue(V value) {
		// TODO Auto-generated method stub
		this.value = value;
		return value;
	}


}

타입은 두개 이상의 멀티 타입피라미터를 사용할 수 있고, 이 경우 각 타입 피라미터를 콤마로 구분합니다. 

 

 

 

제네릭 메소드

 

제네릭 메서드를 정의할때는 리턴타입이 무엇인지 상관 없이 내가 제네릭 메서드라는 것을 

컴파일러에게 알려줘야 합니다. 그러기 위해서 리턴타입을 정의하기 전에

제네릭 타입에 대한 정의를 반드시 명시해야 합니다. 

 

또 다른 중요한 점은 

제네릭 클래스가 아닌 일반 클래스 내부에서도 제네릭 메서드를 정의할 수 있습니다. 

그 말은, 클래스에 지정된 타입 피라미터와 제네릭 메서드에 정의된 타입 피라미터는 상관이 없다는 것입니다. 

즉, 제네릭클래스에 <T>를 사용하고, 같은 클래스의 제너릭 메서드에도 <T> 로 같은  이름 피라미터를 사용해도

둘은 전혀 상관없습니다. 

 

package practice;

public class People<T, M> {

	private T name;
	private M age;

	public People() {
		// TODO Auto-generated constructor stub
	}

	public People(T name, M age) {
		super();
		this.name = name;
		this.age = age;
	}

	public T getName() {
		return name;
	}

	public void setName(T name) {
		this.name = name;
	}

	public M getAge() {
		return age;
	}

	public void setAge(M age) {
		this.age = age;
	}

	//Generic Method
	public static<T, V> boolean compare(People<T,V> p1, People<T,V>p2 ) {

		boolean nameCompare = p1.getName().equals(p2.getName());
		boolean ageCompare = p1.getAge().equals(p2.getAge());

		return nameCompare && ageCompare;

	}


}
package practice.run;

import practice.People;

public class ExGeneric {

	public static void main(String[] args) {
		//타입 파라미터 지정
        People<String,Integer> p1 = new People<String,Integer>("Jack",20);
        //타입 파라미터 추정
        People<String,Integer> p2 = new People("Steve",30);
        //Generic Mothod 호출
        boolean result = p1.compare(p1, p2);
        System.out.println(result);

	}

}

 

 

 

 

 

제네릭 와일드 카드

 

package practice;

import java.util.List;

public class Calcu {
	public void printList(List<?> list) {
		for (Object obj : list) {
			System.out.println("obj" + obj + " ");
		}
	}

	public int sum(List<? extends Number> list) {
		int sum = 0;
		for (Number i : list) {
			sum += i.doubleValue();
		}
		return sum;
	}

	public List<? super Integer> addList(List<? super Integer> list) {
		for (int i = 1; i < 5; i++) {
			list.add(i);
		}
		return list;

	}
}

와일드카드 타입에는 총 세가지의 형태가 있으며 물음표(?)라는 키워드로 표현됩니다.

제네릭타입<?> : 타입 파라미터를 대치하는 것으로 모든 클래스나 인터페이스타입이 올 수 있습니다.

제네릭타입<? extends 상위타입> : 와일드카드의 범위를 특정 객체의 하위 클래스만 올 수 있습니다.

제네릭타입<? super 하위타입> : 와일드카드의 범위를 특정 객체의 상위 클래스만 올 수 있습니다.

'자바 한계단' 카테고리의 다른 글

직렬화 Serialize 란?  (0) 2022.01.27
자바 Iterator, Enumeration 인터페이스  (0) 2021.12.26
Map 컬렉션 - HasMap, Hashtable  (0) 2021.12.08
다형성 ploymorphism  (0) 2021.10.17
상속 Inherit  (0) 2021.10.17