ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 제네릭(Generic) 이란?
    JAVA 2020. 11. 15. 21:53
    반응형

    자바에서 타입을 지정해주는 제네릭에 대해 알아보도록 하자.

     

     


     

    제네릭(Generic) 이란?

     

    List나 Map과 같은 Collection을 사용하다보면 List<String>, Map<String, Integer>와 같이 "<>" 사이에 타입을 명시해놓는 형태를 본 적이 많을 것입니다. 이게 제네릭 입니다.

     

    이걸 왜 사용하는 것일까요?

    제네릭을 사용하지 않고 ArrayList를 만들어 봅시다. ArrayList에는 기본적으로 모든 클래스의 조상인 Object 타입이 올 수가 있습니다. 여기에 문자열을 집어넣고 이를 get 메소드를 통해 반환하려고 하면 반드시 casting(형변환)을 해주어야 합니다. 수만, 수십만개의 데이터를 꺼내야 한다면 마찬가지로 수만, 수십만번의 casting을 해주어야 하기에 시스템 성능의 큰 저하를 가져오게 됩니다.

    그리고 만약 이 상태로 casting을 잘못하게 된다면 컴파일 과정에선 이상이 없는데 실행을 시키면 에러가 발생하게 됩니다.

     

    반면에 제네릭을 사용하면 타입을 강제로 지정하여 casting할 필요가 없어지고 잘못된 타입이 사용될 경우 컴파일러에서 에러라고 알려주기 때문에 에러를 사전에 방지할 수 있게 됩니다.

     

    ArrayList list1 = new ArrayList();
    list1.add("문자열");
    String str1 = (String) list1.get(0);
    
    ArrayList<String> list2 = new ArrayList();
    list2.add("문자열");
    String str2 = list2.get(0);

     

    즉, 제네릭을 통하여

    1. 컴파일 시 타입 체크를 통해 에러를 사전에 방지해 타입 안정성을 가짐

    2. casting을 제거

    라는 장점을 가지게 됩니다.

     

     

     

     

    제네릭 타입

     

    제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스를 말합니다. 클래스 또는 인터페이스 뒤에 "<>" 부호가 붙고 사이에 타입 파라미터가 위치합니다.

    이 타입 파라미터의 경우 정해진 규칙은 없지만 일반적으로 대문자 알파벳 한글자로 표현합니다.

     

    <T> Type
    <E> Element
    <K> Key
    <N> Number
    <V> Value

     

    //제네릭 클래스
    class MyGenric<T>{ //Type parameter
    	T obj;
    	void add(T obj) {
    		this.obj = obj;		
    	}
    	T get() {
    		return this.obj;
    	}
    }
    
    
    //제네릭 인터페이스
    interface GenInterface<T> {
    	T get();
    }
    
    class Generic implements GenInterface<String> {
    	@Override
    	public String get() {
    		return null;
    	}
    	
    }

     

     

     

     

    멀티 타입 파라미터

     

    제네릭 타입은 두 개 이상의 멀티 파라미터를 이용할 수 있습니다. 이 경우 각 타입 파라미터는 콤마로 구분합니다.

     

    interface MapInterface<K, V> {
    	K getKey();
    	V getValue();
    }
    
    class MyMap<K, V> implements MapInterface<K, V> {
    	
    	private K key;
    	private V value;
    	
    	public MyMap(K key, V value) {
    		this.key = key;
    		this.value = value;
    	}
    
    	@Override
    	public K getKey() {
    		return this.key;
    	}
    
    	@Override
    	public V getValue() {
    		return this.value;
    	}
    	
    }

     

     

     

     

    제네릭 메소드

     

    제네릭 메소드는 파라미터 타입과 리턴타입으로 타입 파라미터를 갖는 메소드를 말합니다.

    선언 방법은 리턴 타입 앞에 "<>" 기호를 추가하고 타입 파라미터를 기술한 뒤, 리턴 타입과 파라미터 타입으로 타입 파라미터를 사용하면 됩니다.

     

    public static <K, V> boolean compare (MyMap<K, V> map1, MyMap<K, V> map2) {
    	return map1.getKey().equals(map2.getKey()) && map1.getValue().equals(map2.getValue());
    }

     

     

     

    제한된 타입 파라미터

     

    타입 파라미터에 지정되는 구체적인 타입이 제한될 필요가 있는 경우도 발생합니다.

    숫자 연산과 관련된 메소드를 구현할 때 파라미터 값으로 Number 타입 또는 그 하위 클래스 타입 (Integer, Double 등) 만 제한하고 싶을 때 아래와 같이 <T extends 최상위 타입> 형태로 사용하면 됩니다.

     

    public static <T extends Number> void check(T t1, T t2) {
    	System.out.println(t1.getClass().getName());
    	System.out.println(t2.getClass().getName());
    }
        
        
    public static void main(String[] args) {
    	check(1, "문자열"); //에러 발생	
    }
    	

     

     

     

    와일드카드

     

    와일드카드는 제네릭 타입을 파라미터나 리턴 타입으로 사용할 때 타입 파라미터를 제한할 목적으로 사용하는 것입니다.

    참고로 제한된 타입 파라미터의 경우, 제네릭 타입과 제네릭 메소드를 선언할 때 제한하는 것입니다.

     

    class WildCard {
    	public void method1(List<?> list) {
    		//생략
    	}
    	
    	public int method2(List<? extends Number> list) {
    		//생략
    		return 0;
    	}
    	
    	public Set<? super Integer> method3(Set<? super Integer> set) {
    		//생략
    		return null;
    	}
    }

     

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

     

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

    제네릭타입<? extends 상위타입> (상위 클래스 제한) : 타입 파라미터를 대치하는 구체적인 타입으로 특정 객체의 하위 클래스만 올 수 있습니다.

    제네릭타입<? super 하위타입> (하위 클래스 제한) : 타입 파라미터를 대치하는 구체적인 타입으로 특정 객체의 상위 클래스만 올 수 있습니다.

     

     

     

     

    References

    -coding-factory.tistory.com/573

    -cornswrold.tistory.com/180

    -medium.com/%EC%8A%AC%EA%B8%B0%EB%A1%9C%EC%9A%B4-%EA%B0%9C%EB%B0%9C%EC%83%9D%ED%99%9C/java-generic-%EC%9E%90%EB%B0%94-%EC%A0%9C%EB%84%A4%EB%A6%AD-f4343fa222df

     

    728x90

    'JAVA' 카테고리의 다른 글

    [Study] 자바 2주차 과제  (0) 2020.11.21
    [Study] 자바 1주차 과제  (0) 2020.11.17
    [JAVA] StringTokenizer  (0) 2020.10.28
    클래스, 객체, 인스턴스  (0) 2020.09.21
    자바의 메모리 구조  (0) 2020.09.18

    댓글

Designed by Tistory.