본문 바로가기
Programming/Java

[이펙티브자바] 아이템29. 이왕이면 제네릭 타입으로 만들라

by 읽고 쓰는 개발자 2023. 4. 8.

아이템29. 이왕이면 제네릭 타입으로 만들라

핵심정리

  • 배열을 사용하는 코드를 제네릭으로 만들 때 해결책 두 가지. (성능 등의 이유로 배열을 사용해야 할 때)
    • 첫번째 방법 : 제네릭 배열(E[]) 대신에 Object 배열을 생성한 뒤에 제네릭 배열로 형변환 한다.
      • 형변환을 배열 생성시 한 번만 한다.
      • 가독성이 좋다.
      • 힙 오염이 발생할 수 있다.
    • 두번째 방법 : 제네릭 배열 대신에 Object 배열을 사용하고, 배열이 반환한 원소를 E로 형변환한다.
      • Object 배열을 사용하기 때문에 힙 오염 발생 안한다.
      • 원소 꺼낼 때마다 형변환을 해줘야하는 점이 단점
  • 예) 스택 : Element 안에 객체가 들어가는 자료구조에서, 런타임시 ClassCastException을 줄이는데 유용
    • Object 타입을 사용할 때처럼 형변환을 하지 않아도 된다.
    • 제네릭 타입으로 선언 + 배열은 Object 타입으로 생성 ( 제네릭 배열은 생성이 안되기에 )

완벽공략

  • 한정적 타입 매개변수 (Bounded Type Parameters)
    • 타입 소거
      • 제네릭 타입은 컴파일 후 타입 소거가 되어 Object 타입으로 생성된다. (제네릭 타입은 지워짐)
      • 타입 제한을 하면, 상속/구현하지 않은 타입으로 선언시 컴파일 에러가 남
      • 타입 제한을 하면, 컴파일 후 제한한 타입으로 타입 캐스팅을 한다. (E -> Number로 변경되었다고 보면 됨)
      • 타입을 한정지으면 이전에 동작하던 코드가 문제될 수 있다. (Object 배열 -> Number 배열로 캐스팅한 것과 같은 위험. : 반대는 가능. 공변이니까)
      • 배열 자체는 한정지은 타입으로 생성을 하고, 꺼낼 때 E 타입으로 꺼내주면 됨
    • 매개변수화 타입을 특정한 타입으로 한정짓고 싶을 때 사용할 수 있다.
      • <E extends Number>, 선언할 수 있는 제네릭 타입을 Number를 상속(extends)했거나 구현한(implements) 클래스로 제한한다.
    • 제한한 타입의 인스턴스를 만들거나, 메서드를 호출할 수도 있다.
      • <E extends Number>, Number 타입이 제공하는 메서드를 사용할 수 있다.
    • 다수의 타입으로 한정할 수 있다. 이 때 클래스 타입을 가장 먼저 선언해야 한다.
      • <E extends Number & Serializable>, 선언할 제네릭 타입은 Integer와 Number를 모두 상속 또는 구현한 타입이어야 한다.

출처 : 백기선님 - 이펙티브 자바 완벽 공략 2부