제네릭(Generic)

뜻 자체는 일반적인.

제네릭(Generic)은 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것을 의미한다. 즉, 클래스 정의 시 특정(Specific) 타입을 미리 지정해주는 것이 아니라 인스턴스를 생성할 때 지정할 수 있도록 하는 일반(Generic) 타입이라는 것이다.

 

출처: 생활코딩

 

  • 제네릭의 타입
타입 설명
<T> Type
<E> Element
<K> Key
<V> Value
<N> Number
<R> Result

사실 <>안의 알파벳은 한글자일 필요도 없고 설명과 맞춰 사용할 필요도 없으나 위와 같은 형태로 관례적으로 사용되고 있다.  

 

  • 제네릭을 왜 사용할까?

- 제네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있다.

- 클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하고 변환해줄 필요가 없다. 즉, 관리하기가 편하다.

- 비슷한 기능을 지원하는 경우 코드의 재사용성이 높아진다.

 

// 런타임시 에러
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타입은 해당 실행 블록안에서만 유효하며 타입 파라미터로 명시할 수 있는 것은 참조 타입 뿐이다. (기본 타입은 불가)

 

 

  • 제네릭 클래스
class GenericExample<T> {
    private T t;

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

 

  • 제네릭 인터페이스
//인터페이스
interface InterfaceGenericExample<T> {
    T example();
}

//구현 클래스
class GenericExample implements InterfaceGenericExample<String> {

    @Override
    public String example() {
        return null;
    }
}

 

  • 제네릭 멀티 타입 파라미터 사용

2개 이상의 멀티 타입으로 사용한다. 

class MultiGenericExample<K, V> {

    private K key;
    private V value;

    @Override
    public K getKey() {
        return this.key;
    }

    @Override
    public V getValue() {
        return this.value;
    }

    @Override
    public V setValue(V value) {
        this.value = value;
        return value;
    }
}

 

이 방법을 사용하는 대표적인 예가 HashMap이다

public class HashMap <K, V> {...}

//----------------------------

HashMap<Integer,String> map = new HashMap<>();
map.put(1,"사과"); //값 추가
map.put(2,"바나나");
map.put(3,"포도");

 

  • 제네릭 메소드

매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드

// 제네릭 메소드 선언
// 맨 앞에 사용 타입파라미터 선언, 리턴 타입: Box<T>, 매개 변수 타입: T 
public <T> Box<T> boxing(T t) {
    Box<T> box = new Box<T>();
    box.set(t);
    return box;
}

// 호출
public class BoxingMethodExample {
	public static void main(String[] args) {
		Box<Integer> box1 = <Integer> boxing(100);
		int intValue = box1.get();
		
		Box<String> box2 = boxing("홍길동");
		String strValue = box2.get();
	}
}

 

 

  • 와일드 카드

모든 타입을 대신할 수 있는 타입을  와일드카드라고 하고 ? (물음표)로 표시하며 총 3가지 형태로 이용한다.

 

1) <?> : 모든 클래스나 인터페이스 타입이 올 수 있다.

public static void registerCourse(Course<?> course) {
	System.out.println(course.getName() + " 수강생: " + Arrays.toString(course.getStudents()));
}

 

2) <? extends 상위타입> : 상한 경계 와일드 카드라 하며 와일드카드 타입의 최상위 타입을 정의하여 한계를 정한다.

아래 코드 같은 경우는 최상위 타입이 Student라 정해졌기 때문에 이와 동일하거나 그 이하의 타입만 ?에 들어올 수 있다.

public static void registerCourseStudent(Course<? extends Student> course) {
	System.out.println(course.getName() + " 수강생: " + Arrays.toString(course.getStudents()) );
}

 

3) <? super 하위 타입> : 하한 경계 와일드 카드라 하며 와일드카드 타입의 최하위 타입을 정의하여 한계를 정한다.

아래 코드 경우 최하위 타입이 Worket라고 정해졌기 때문에 이와 동일하거나 그 이상인 타입만 ?에 들어올 수 있다. 

public static void registerCourseWorker(Course<? super Worker> course) {
	System.out.println(course.getName() + " 수강생: " + Arrays.toString(course.getStudents()));
}

 

 

  • 제네릭 타입의 상속과 구현

제네릭 타입도 다른 타입과 마찬가지로 부모가 될 수 있으며 자식 클래스는 추가로 타입 파라미터를 가질 수 있다. 

// 제네릭 타입의 상속
public class ChildProduct<T, M, C> extends Product<T, M> {...}

 

 

또한 인터페이스도 될 수 있으며 이를 구현한 클래스도 제네릭 타입이 된다.

// 제네릭 인터페이스
public interface Storage<T> {
	//추상메소드
	public void add(T item, int index);
}
// 제네릭 구현 클래스
public class StorageImpl<T> implements Storage<T> {
	private T[] array;
	
	public StorageImpl(int capacity) {
		this.array = (T[]) (new Object[capacity]);
	}
	
	@Override
	public void add(T item, int index) {
		array[index] = item;
	}
}

 

 

 

 

 

 

 

자바 [JAVA] - 제네릭(Generic)의 이해

정적언어(C, C++, C#, Java)을 다뤄보신 분이라면 제네릭(Generic)에 대해 잘 알지는 못하더라도 한 번쯤은 들어봤을 것이다. 특히 자료구조 같이 구조체를 직접 만들어 사용할 때 많이 쓰이기도 하고

st-lab.tistory.com

 

[Java] 제네릭과 와일드카드 타입에 대해 쉽고 완벽하게 이해하기(공변과 불공변, 상한 타입과 하

이번에는 공변과 불공변에 대해서 먼저 알아보고, 이후에 제네릭과 와일드카드에 대해 알아보도록 하겠습니다. 많은 분들이 어려워하는 제네릭인 만큼 쉽게 풀어서 설명하려고 노력했는데, 많

mangkyu.tistory.com

 

[Java]STEP2 - 2) 제네릭 메소드(Generic Method), 와일드카드, 제네릭 타입의 상속과 구현

본 게시글은 도서 "이것이 자바다" 동영상 강의를 듣고 기록하는 TIL(Today I Learned) 입니다. 모든 저작권은 출판사 한빛미디어와 신용권님께 있음을 알립니다.👍 이번 게시물은 저번 게시물에 이

kyleyj.tistory.com

 

제네릭 - 생활코딩

제네릭이란? 제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 말이 어렵다. 아래 그림을 보자. 위의 그림은 아래의 코드를 간략화한 것이다. package or

opentutorials.org

 

+ Recent posts