• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [Java 정리] Generics
        2022년 04월 09일
        • starryeye
        • 작성자
        • 2022.04.09.:00
        반응형

        Generics

        다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스를 컴파일 시점에 타입 체크를 해주는 기능

        객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어듬

        (generic 타입은 컴파일러가 컴파일할 때만 사용하고 제거)

         

        Generics의 장점

        1. 타입 안정성을 제공

        2. 타입 체크와 형변환을 생략할 수 있으므로 코드가 간결해짐

        -> 객체의 타입을 미리 명시해줘서 번거로운 형변환을 줄여준다.

         

        Generic Class 선언

        class Box<T> {
        	
            T item;
            
            void setItem(T item) { this.item = item; }
            T getItem() { return item; }
        }

        // generic type T 선언

         

        T : 타입 변수

         

        Generic Class인 Box Class의 객체 생성

        Box<String> b = new Box<String>();

        위 와 같이 참조변수와 생성자에 실제 타입을 지정해준다.

         

         

        용어

        class Box<T> {}

        Box<T> : generic class, T box라 부름

        T : 타입 변수, 타입 매개변수

        Box : 원시 타입

         

        제한

        class Box<T> 
        {	
            static T item; //err1
            static int compare(T t1, T t2) {} //err2
            
            T[] itemArr; //OK1
            
            T[] getArray() {
                T[] tmpArr = new T[itemArr.length]; //err3
            }
        }

        위 코드는 컴파일에러가 발생한다.

        T는 인스턴스 변수로 간주되기 때문에 static 맴버에 타입 변수 T를 사용 할 수 없다.(err1, err2)

        generic 배열 타입의 참조 변수를 선언하는건 가능(ok1)

        하지만, 배열을 직접 생성하는건 불가능.(err3)

        -> (new 연산자때문임, new연산자는 컴파일 시점에 타입 T가 뭔지 정확히 알아야 함. 컴파일 시점에 이 코드만 놓고는 T가 어떤 타입인지 모르자나)

        err3 방법>

        1. new 연산자 대신 Reflection API의 newInstance() 를 사용하여 동적으로 객체 생성

        2. Object 배열을 생성하여 T[]로 형변환하여 복사

         

         

        Generic 메서드

        class FruitBox<T> {
        	...
            static <T> void sort(List<T> list, Comparator<? super T> c) {
            ...
            }
        }

        static 맴버에는 타입 매개 변수를 사용할 수 없지만, 메서드에 generic 타입을 선언하고 사용하는 것은 가능

        (참고로 클래스에 선언된 T와 메서드에 선언된 T는 문자만 같을 뿐 서로 다른것이다.)

         

        public static <T extends Comparable<? super T>> void sort(List<T> list)

        List<T> : 타입 T를 요소로 하는 List를 매개변수로 허용

        T extends Comparable : T는 Comparable을 구현한 클래스

        Comparable<? super T> : T 또는 그 조상의 타입을 비교하는 Comparable이어야 함

         

         

        형변환 + 라이브러리 읽기

        java.util.Optional

        public final class Optional<T> {
        	...
            private static final Optional<?> EMPTY = new Optional<>();
            private final T value;
            	...
            public static<T> Optional<T> empty() {
            	Optional<T> t = (Optional<T>) EMPTY;
                return t;
            }
           	...
        }

        <?>는 <? extends Object>를 줄여 쓴 것

        <>안에 생략된 타입은 Object 이다.

         

        EMPTY 타입을 Optional<Object>가 아닌 Optional<?>로 한 이유는 Optional<T>로 형변환이 가능하기 때문이다.

        Optional<?> wopt = new Optional<Object>();
        Optional<Object> oopt = new Optional<Object>();
        
        Optional<String> sopt = (Optional<String>)wopt; //OK
        Optional<String> sopt = (Optional<String>)oopt; //err

        wopt : Object --> ? --> String

        oopt : Object --> String

        empty()의 반환 타입이 Optional<T> 이므로 EMPTY를 Optional<T>로 형변환해야 하는데, 위의 코드 처럼 Optional<T>로 형변환 불가능함

         

        <정리>

        Optional<Object>를 Optional<String>으로 직접 형변환 불가능

        와일드 카드가 포함된 genericc 타입으로 형변환하면 가능

         

        Optional<Object> --> Optional<T> // 불가능

        Optional<Object> --> Optional<?> --> Optional<T> // 가능

         

         

        읽어보면 좋은 포스팅

        https://st-lab.tistory.com/153

        반응형

        'Java' 카테고리의 다른 글

        [Java 정리] Garbage Collector 1  (0) 2022.07.30
        [Java 정리] 내부 클래스  (0) 2022.07.28
        [Java 정리] Exception, Error  (0) 2022.07.15
        [Java 정리] Annotation  (0) 2022.04.09
        [Java 정리] enum  (0) 2022.04.09
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바