ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java - 제네릭(Generics)
    Java/java study 2022. 4. 3. 22:26
    728x90
    반응형

     

     

    제네릭(Generics)

    • 제네릭 사용법
    • 제네릭 - 바운디드 타입
    • 제네릭 - 와일드카드
    • 제네릭 메서드

     

     

     

     

    제네릭(Generics)란?

     

     지네릭스는 다양한 타입의 객체를 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형 변환의 번거로움을 줄일 수 있다.

     

     

    - 타입 안정성

     의도하지 않은 타입의 객체가 저장되는 것을 막고, 저장된 객체를 꺼내올 때 원래의 타입과 다른 타입으로 잘못 형 변환되어 발생할 수 있는 오류를 줄여준다.

     

     

    - 제네릭을 사용하는 이유

    • 제네릭 타입을 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있기 때문
    • 자바 컴파일러는 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대해 강한 타입 체크를 한다.
    • 실행 시 타입 에러가 나는 것보다 컴파일 시에 미리 타입을 강하게 체크하여 에러를 사전에 방지할 수 있다.
    • 제네릭 코드를 사용하면 타입을 국한하기 때문에 요소를 찾아올 때 타입 변환을 할 필요가 없어 프로그램 성능이 향상되는 효과를 얻을 수 있다.

     


     

    제네릭 사용법

     

     - 제네릭 클래스 선언

    public class Box<T> {
    
        private T type;
        
        public void set(T type) { this.type = type }
        public T get() { return type; }
    }
    • T를 타입 변수(Type variable) 이라 한다.
    • 타입 변수는 상황에 맞는 의미 있는 문자를 선택하여 사용할 수 있다.
         - T : Type, E : Element, K : Key, V : Value
    • 과거에는 Object로 다양한 종류의 타입을 다룰 때 사용했지만 타입 체크 시 문제가 발생했다.

     

    - 제네릭 클래스 사용

    Box<String> box = new Box();
    // 타입 변수에 String을 전달하였으므로 아래와 같다.
    public class Box {
    
        private String type;
        
        public void set(String type) { this.type = type }
        public String get() { return type; }
    }
    
    Box<int> box = new box();
    // 타입 변수에 int를 전달하였으므로 아래와 같다.
    public class Box {
    
        private int type;
        
        public void set(int type) { this.type = type }
        public int get() { return type; }
    }

     

     

    - 지네릭스의 제한

    • 모든 객체에 대해 동일하게 동작해야 하는 static멤버에 타입 변수 T를 사용할 수 없다.
    • 지네릭 타입의 배열을 생성할 수 없다.(컴파일러가 컴파일 시점에 타입 T 가 무엇인지 알아야 하기 때문)

     

     


     

    제네릭 주요 개념 - 바운디드 타입(Bounded Type)

     

    • 바운디드 타입은 특정 타입의 서브 타입으로 제한한다.
    • 클래스나 인터페이스 설계할 때 가장 흔하게 사용할 정도로 많이 볼 수 있는 개념이다.

     

    public class Box<T extends S> {
    
    	...
    }
    • 타입 변수 T는 S의 서브 타입만 허용한다.

     

    제네릭 주요 개념 - 와일드카드(WildCard)

     

    - Unbounded WildCard

    • ? 와 같은 형태로 물음표만 가지고 정의한다.( ex. List<?> )
    • 내부적으로 Object로 정의되어 있기 때문에 모든 타입의 인자를 받을 수 있다.
    • 타입 파라미터에 의존하지 않는 메서드만을 사용하거나 Object 메서드에서 제공하는 기능으로
      충분한 경우 사용한다.
    • Object 클래스에서 제공되는 기능을 이용하여 구현하는 메서드에서 사용
    • 타입 파라미터에 의존적이지 않는 일반 클래스의 메서드를 사용하는 경우에 사용
      ex) List, clear, List, size 등

     

    - Upper Bounded Wildcard

    • 특정 클래스의 자식 클래스만을 인자로 받을 때 사용한다.
    • 사용할 수 있는 기능은 특정 클래스에서 정의된 기능만 사용할 수 있다.
      ex) List<? extends Skill>

     

    - Lower Bounded Wildcard

    • 특정 클래스의 부모 클래스만을 인자로 받을 수 있다.
      ex) List<? supper Skill>

     

    지네릭 메서드

     

    • 메서드 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라 한다.
    • static 멤버에는 타입 매개변수를 사용할 수 없지만, 메서드에는 사용이 가능하다.
    • 지네릭 타입의 선언 위치는 반환 타입 바로 앞이다.
    static <T> void sort(List<T> list, Comparator<? super T> c)

     

    • 제네릭 클래스에 정의된 타입 매개변수와 제네릭 메서드에 정의된 타입 매개변수는
      서로 다른 타입 변수다.(같은 타입 문자 T를 사용해도 같은 타입 변수가 아니다)
    class FruitBox<T>{
    	...
    	static <T> void sort(List<T> list, Compatrator<? super T> c){
    		...
    	}
    }

     

     

    예시

    public static void printAll(
    			ArrayList<? extends Product> list,
    			ArrayList<? extends Product> list2){
        
    	for(Unit u : list){
    		System.out.println(u);
    	}
    }
    
    
    // 지네릭 메서드로 변경
    
    public static void printAll(
    			ArrayList<? extends Product> list,
    			ArrayList<? extends Product> list2){
                
    	for(Unit u : list){
    		System.out.println(u);
    	}
    }

     

    728x90
    반응형

    'Java > java study' 카테고리의 다른 글

    Java - 람다식  (0) 2022.04.10
    Java - Input과 Output(I/O)  (0) 2022.03.27
    Java - 애노테이션(annotation)  (0) 2022.03.06
    Java - enum이란  (0) 2022.02.27
    Java - Thread  (0) 2022.02.20

    댓글

Designed by Tistory.