Java Generic 정리

프로그래밍|2016. 1. 13. 10:19

설계를 할때마다 Generic 사용법을 잊어먹는 경우가 많아 이해하기 쉬운 수준으로 정리를 해보려고 한다.



Class generic type


Class generic type은 다음과 같은 방법으로 클래스가 작성된다.

어떤 경우에 사용하면 되는지에 대해서는 ArrayList 클래스를 생각하면 될 것이다.

ClassGenericType<String> classGenericType = new ClassGenericType<>();

class ClassGenericType<T> {

        private T t;

 

        public void set(T t) {

               this.t = t;

        }

        public T get() {

               return t;

        }

}



Interface generic type


Interface generic type 또한 Class generic type과 사용방법이 유사하다.

아래는 제너릭 타입이 두 개 선언된 것을 알 수 있는데 <T1, T2> 이는 abstract method의 제너릭 타입을 다르게 주고 싶을 때 사용하면 된다.

interface InterfaceGenericType<T1, T2> {

        T1 doSomething(T2 t);

        T2 doSomething2(T1 t);

}


InterfaceGenericType 인터페이스 구현 클래스

class InterfaceGenericTypeImpl implements InterfaceGenericType<String, Integer> {

        @Override

        public String doSomething(Integer t) {

               return null;

        }

 

        @Override

        public Integer doSomething2(String t) {

               return null;

        }

}




Method Generic Type


메소드 제너릭 타입은 클래스에 제너릭 타입을 선언하지 않아도 되며 아래와 같이 필요한 메서드에 제너릭 타입을 선언하면 된다. 여기서 유념해야 할 점은 메서드 아규먼트에 타입 매개변수 T가 선언되어 있으면 메서드의 리턴 타입 앞에 제너릭 타입을 선언해야 한다. int 옆에 있는 <T>

쉽게 생각해서 T, E, V, U 등등의 타입 매개변수가 선언되어 있다면 제너릭 타입이 필수적으로 선언되어야 한다라는 것이다.


class MethodGenericType {

        public static <T> int methodGeneric(T[] list, T item) {

               int count = 0;

               for (T t : list) {

                       if (item == t) {

                              count++;

                       }

               }

               return count;

        }

}



Wildcard Generic Type


?는 알 수 없는 타입

<?> : 모든 객체 자료형, 내부적으로는 Object로 인식
<? super 객체자료형> : 명시된 객체자료형의 상위 객체, 내부적으로는 Object로 인식
<? extends 객체자료형> : 명시된 객체 자료형을 상속한 하위객체, 내부적으로는 명시된 객체 자료형으로 인식


extends 뒤에는 클래스, 인터페이스가 올 수 있다. (E, ? 인 경우 사용 가능)

class WildcardGenericType {

 

        public List<? extends Number> method1() {

               return new ArrayList<Long>();

        }

 

        // Bounded wildcard parameterized type

        public <T> List<? extends String> method2(T param) {

               return new ArrayList<String>();

        }

 

        // Unbounded wildcard parameterized type

        public List<?> method3() {

               return new ArrayList<>();

        }

}



Not Allowed Generic Type


허용하지 않는 사용법

class NotAllowedGenericType<T> {

 

        // static 필드는 제너릭 타입을 가질 수 없음

//      private static T t;

 

        public NotAllowedGenericType() {

               // T type은 인스턴스로 생성할 수 없음

//             new T();

 

               // primitives 타입으로 제너릭 타입을 선언할 수 없음

//             List<int> list = new ArrayList<>();

        }

}



참고


타입 매개변수는 아래와 같이 존재한다.

E - Element

K - Key
N - Number
T - Type
V - Value

제너릭 타입이 인스턴스화 될 때, 컴파일러는 타입파라미터와 관련된 정보를 제거한다.
제너릭을 사용하기 이전의 라이브러리 등과의 호환성을 유지하기 위함.





댓글()