JAVA

[JAVA] 제네릭

집한구석 2021. 12. 15. 14:11
728x90

제네릭

  • 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법
  • 외부에서 사용자에 의해 타입이 지정되는 것을 의미

제네릭 장점

  1. 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지함
  2. 타입을 외부에서 지정하기 때문에 반환값에 대한 타입 체크와 타입을 따로 검사해줄 필요가 없음
  3. 코드의 재사용성을 증대 시킴

제네릭 타입 종류

타입 설명
<T> Type
<E> Element
<K> Key
<V> Value
<N> Number

제네릭 변성

타입이 있는 언어에는 변성이라는 개념이 있음, 제네릭은 변성에 관련된 3가지 성질을 제공

  1. 공변 : A가 B의 하위 타입일  때, T <A> 가 T<B>의 하위 타입이면 T가 공변 성질을 가지고 있음
  2. 반공변 : A가 B의 하위 타입일 때, T<B>가 T<A>의 하위타입이면 T가 반공변 성질을 가지고 있음
  3. 무공변 : A가 B의 하위 타입일 때, T<A>와 T<B>가 아무 관계도 없으면 무공변

제네릭 무공변 예시

GenericType<A>가 GenericType<B>의 상위 타입이 아님  

Animal animal = new Tiger(); 
Cage<Animal> cage = new Cage<Tiger>(); 
// Cage<Animal>이 Cage<Tiger>의 상위타입이 아니라서 에러 발생

제네릭 공변 예시

extends를 사용하여 공변 처리가 가능함, GenericType<A>가 GenericType<B>의 상위 타입

public static void main(String[] args) {
    List<Integer> ints = List.of(1, 2, 3, 4, 5);
    sum(ints);
}

// extends 키워드를 통하여 공변처리함
public static Number sum(List<? extends Number> numbers) {
    long sum = 0;
    for (Number number : numbers) {
      sum += number.longValue();
    }
    return sum;
}

제네릭 반공변 예시

super를 사용하여 반공변 처리가 가능함

// People <- Student <- StudentPresident
People people = new People();
Student student = new Student();
StudentPresident studentPresident = new StudentPresident();

// ?는 Student보다 큰(Student가 확장된) 클래스
List<? super Student> covarianceList = new ArrayList<>();
// covarianceList.add(people); // Compile Error
covarianceList.add(student);
covarianceList.add(studentPresident);

List<Student> covarianceList2 = new ArrayList<>();
// covarianceList2.add(people); // Compile Error
covarianceList2.add(student);
covarianceList2.add(studentPresident);


// true.
System.out.println(covarianceList.equals(covarianceList2));

 

'JAVA' 카테고리의 다른 글

[JAVA] PriorityQueue  (0) 2022.02.06
[JAVA] 람다표현식  (0) 2022.01.01
[JAVA] 리플렉션  (0) 2021.12.12
[JAVA] 데코레이터 패턴  (0) 2021.12.10
[JAVA] 프록시패턴  (0) 2021.12.09