베어_
TechBear
베어_
전체 방문자
오늘
어제
  • 분류 전체보기 (336)
    • Spring (33)
      • 개념 (13)
      • Security (5)
      • 실습 (1)
      • 토비 스프링 (11)
    • JPA (6)
    • 프로젝트 기록 (24)
    • DB (13)
    • JAVA (18)
    • 알고리즘 (50)
      • 유형정리 (8)
      • Baekjoon (21)
      • LeetCode (18)
    • 디자인패턴 (0)
    • 개발서적 (79)
      • Effective Java (78)
      • 객체지향의 사실과 오해 (1)
    • 독후감 (4)
    • 보안 (2)
    • 운영체제(OS) (53)
      • 공룡책 (53)
    • 컴퓨터 네트워크 (28)
      • 컴퓨터 네트워크 하향식 접근 (23)
    • 자료구조 (1)
    • DevOps (2)
    • 앱 개발 (20)
      • 안드로이드 스튜디오 (20)

블로그 메뉴

    공지사항

    인기 글

    태그

    • C++
    • 자바
    • 운영체제
    • 이펙티브자바
    • 백준
    • 토비스프링
    • dfs
    • BFS
    • Spring
    • 스레드
    • 스프링
    • 자바8
    • 코드업
    • 스프링시큐리티
    • jpa
    • 데이터베이스
    • 함수형인터페이스
    • java
    • 알고리즘
    • leetcode

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    베어_

    TechBear

    개발서적/Effective Java

    [Effective Java] raw 타입은 사용하지 말자

    2023. 5. 27. 01:37

    제네릭 클래스/인터페이스

    클래스와 인터페이스 선언에 타입 매개변수가 쓰이면 제네릭 클래스 혹은 제네릭 인터페이스라 한다.
    제네릭 타입은 일련의 매개변수화 타입을 정의한다. => List, Map, Integer etc

    raw 타입

    제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말하며 List에서 List가 raw 타입이다. 다음과 같이 raw타입으로 변수를 선언할 수 있다.

    private final Collection stamps = ...; 

    하지만 이 코드를 사용하면 stamp대신 coin을 넣어도 아무 오류 없이 컴파일되고 실행된다. 이 에러가 발견되는 시점은 다음과 같이
    이 동전을 꺼낼 때이다.

    Stamp stamp = (Stamp) stamps.get(0); 

    하지만 제네릭을 활용하면 이 정보가 주석이 아닌 타입 선언 자체에 녹아들기 때문에 더 안전한 프로그래밍이 가능해진다.
    이런 raw타입은 하위 호환성 때문에 존재한다.

    다음과 같이 List<Object>처럼 임의 객체를 허용하는 매개변수화 타입은 괜찮다. -> 모든 타입을 허용한다는 의사를 컴파일러에게 명확히 전달한다

    비한정적 와일드카드 타입 (Unbounded wildcard type)

    원소의 타입을 몰라도 되는 raw 타입을 쓰고 싶어질 수 있다.

    static int numElementsInCommon(Set s1, Set s2) {
        int result = 0;
        for (Object o1 : s1) {
            if(s2.contains(o1))
                result++;
        return result;

    이런 경우에는 동작은 하지만 타입 불변식을 훼손하기 쉽다. 이처럼 제네릭 타입을 쓰고 싶지만 실제 타입 매개변수가 무엇인지 신경 쓰고 싶지 않다면 물음표를 사용하자.

    static int numElementsInCommon(Set<?> s1, Set<?> s2) { ... }

    instanceof 연산자와 제네릭

    런타임에는 제네릭 타입 정보가 지워지므로 instanceof 연산자는 비한정적 와일드카드 타입 이외의 매개변수화 타입에는 적용할 수 없다.
    또 raw 타입과 비한정적 와일드카드타입의 instanceof는 완전히 똑같이 동작한다. 따라서 제네릭 타입에 instanceof를 사용하는 경우에는 제네릭을 붙이지 않는 것이 깔끔하다.

    if (o instanceof Set) {
        Set<?> s = (Set<?>) o;
    }

    o의 타입이 Set임을 확인한 다음 와일드카드 타입인 Set<?>로 형변환해야 한다. (컴파일러 경고가 안되기 때문)

    저작자표시 비영리 변경금지 (새창열림)
      '개발서적/Effective Java' 카테고리의 다른 글
      • [Effective Java] 배열보다는 리스트를 사용하라
      • [Effective Java] 비검사 경고를 제거하라
      • [Effective Java] 멤버 클래스는 되도록 static으로 만들라
      • [Effective Java] 태그 달린 클래스보다는 클래스 계층구조를 활용하라
      베어_
      베어_
      Today I learned | 문제를 해결하는 개발자

      티스토리툴바