Skip to content

Generics

Yongho Choi edited this page Jan 8, 2017 · 2 revisions
  • Generic class에서 Generic type을 사용하는 메소드는 static으로 선언할 수 없다.

    • Generic은 class가 인스턴스로 될 때 적용이 되는데 static의 경우에는 인스턴스를 만들지 않고 사용하기 때문에 타입을 알 수가 없기 때문이다.
  • Bounded Type Parameter : Type parameter에 제한을 두는 것.

    public class Generics<T extends List> {
    }
    • 여러개를 줄 수도 있다. (multiple bound)

      static <T extends List & Serializable & Comparable & Closeable> void print(T t) {}
      • List, Serializable 등 과 같이 multiple bound로 사용할 수 있는 것들을 인터섹트 타입이라고 한다.
      • 람다식도 사용 가능.
      • class인 경우에는 이렇게 multiple로 사용할 수 없고 하나만 사용할 수 있다.
      • or는 없고 and만 가능.
  • List 사용 시 주의

    List<Integer> intList = new ArrayList<>();
    List<Number> numberList = intList;	// 컴파일 에러
    • Integer는 Number의 하위 클래스이지만 List는 List의 하위 클래스가 아니기 때문에 위 코드는 성립할 수 없다.
    ArrayList<Integer> arrList = new ArrayList<>();
    List<Integer> intList = arrList;	// 정상
    • 여기서는 ArrayList가 List의 하위 클래스가 되므로 정상동작한다.
    public class Generics {
      static class MyList<E, P> implements List<E> {...} 
      public static void main(String[] args) {
        List<String> s1 = new MyList<String, Integer>();
        List<String> s2 = new MyList<String, String>();
      }
    }
    • s1, s2 모두 정상 동작.
    • 뒤에 오는 type parameter는 영향을 주지 않는다.
  • 타입추론에 대해 명시적으로 제공해줄 수 있다.

    class Generics {
      static <T> void method(T t) {}
    
      public static void main(String[] args) {
         Generics.<Integer>method(1);
      }  
    }
    
    
  • wild card

    List<T> list;
    List<?> list;
    • 물음표(?) : wild card
    • T는 타입이 뭔지 알고 정해지면(인스턴스로 생성되면) 그 타입으로 사용하겠다는 의미
    • 물음표(?)는 뭐가 되든 상관 없다는 의미.
      • 위에서는 어떤 타입이 오든 그 타입과 관련된 기능은 관심 없고, 순전히 List의 기능만 사용하겠다는 의미.

Tips

  • parameter를 우리는 혼용해서 사용하고 있는데 선언되어있는 부분은 parameter, 사용하는 쪽에서는 argument라고 한다.

    public class Generics {
      static class Hello<T> {	// type parameter
        T t;
      }
      
      public static void main(String[] args) {
        Hello<String> hello = new Hello<>(); // type argument
      }
    }
  • Raw type : Generic이면서 선언 타입을 주지 않는 경우

    List list = new ArrayList(); // 여기서 List list가 Raw type에 해당.
    • raw type으로 사용할 경우 warning이 많이 발생.
    • warning은 무시하면 안됨
  • Settings -> Build -> Compiler에서 -Xlint 옵션을 주면 warning 메세지에 상세한 설명이 추가된다.

  • 이미 확인된 문제가 없는 warning이라면 @SuppressWarnings("unchecked") 어노테이션을 사용하여 출력되지 않도록 할 수 있다.

  • 비어있는 List를 생성하는 경우

    List<String> c = collections.emptyList();
    • emptyList() 메소드는 앞의 List type으로 타입 추론을 한다.

    • 명시적으로도 가능

      List<String> c = collections.<String>emptyList();

Clone this wiki locally