[아이템27] 비검사 경고를 제거하라

2024. 10. 22. 00:31·1️⃣ 백앤드/이펙티브 자바

1. 제네릭 컴파일 경고

제네릭을 사용하다보면, 수 많은 컴파일 경고를 보게 될 것이다. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고... 등등 수 많은 경고들이 있다.

대부분의 비검사 경고는 쉽게 제거할 수 있기 때문에, 가능한 모든 비검사 경고를 제거하자.

예시로, 코드를 아래처럼 잘못 작성했다고 가정해보자.

Set<Lark> exaltation = new HashSet();

무엇이 잘못되었을까? 경고를 통해 살펴보자.

Item27.java:10: warning: [unchecked] unchecked conversion
        Set<String> mySet = new HashSet();
                            ^
  required: Set<String>
  found:    HashSet
1 warning

컴파일러가 명시해준 것 처럼 타입 매개변수를 명시하지 않고 <> 다이아몬드 연산자만 활용해도, String 을 컴파일러가 추론해준다. 

Set<Lark> exaltation = new HashSet<>();

 

2. @SuppressWarnings("unchecked")

경고를 제거할 수는 없지만, 타입이 안전하다고 확신할 수 있으면 @SuppressWarnings("unchecked") 애너테이션을 달아 경고를 숨기자. 런타임에선 여전히 ClassCastException 을 던지겠지만, 경고 없이 컴파일이 될 것이다.

@SuppressWarnings 애너테이션은 항상 가능한 한 좁은 범위에 적용하자.
보통 변수 선언, 아주 짧은 메서드, 혹은 생성자가 될 것이다.

만약 한 줄이 넘는 메서드나 생성자에 애너테이션이 달려있다면, 지역변수를 새로 선언하여 지역번수 쪽으로 옮기자. 아래 ArrayList 의 toArray 메서드 예시를 통해 살펴보자.

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

ArrayList 를 컴파일하면, 해당 메서드에서 아래 경고가 발생한다.

ArrayList.java:305: warning: [unchecked] unchecked cast
        return (T[]) Arrays.copyOf(elements, size, a.getClass());
                            	   ^
  required: T[]
  found:    Object[]
1 warning

메서드 전체에 달지 말고, 범위가 너무 넓어지니 반환값을 담을 지역변수를 새로 생성하고, 그 변수에 애너테이션을 달아주자.

public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            @SuppressWarnings("unchecked") T[] result =
                (T[]) Arrays.copyOf(elementData, size, a.getClass());
            return result;
        }
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

위 수정을 통해서 깔끔하게 컴파일되고, 비검사 경고도 최소한의 범위로 숨길 수 있게 되었다. 추가로,  @SuppressWarnings("unchecked") 애너테이션을 사용하면서, 그 경고를 무시해도 되는 이유를 항상 주석으로 남기자. 다른 사람이 이해할 수 있는 코드를 작성하고, 수정으로 인한 타입 안정성을 유지못하는 일이 발생하지 않도록 주의를 기울이자.

실제로는 함수 자체에 붙어있는 모습..

'1️⃣ 백앤드 > 이펙티브 자바' 카테고리의 다른 글

[아이템29] 이왕이면 제네릭 타입으로 만들라  (0) 2024.10.24
[아이템28] 배열보다는 리스트를 사용하라  (1) 2024.10.23
[아이템26] 로 타입은 사용하지 말라  (0) 2024.10.18
[아이템25] 톱레벨 클래스는 한 파일에 하나만 담으라  (0) 2024.10.17
[아이템24] 멤버 클래스를 되도록 static 으로 만들어라  (2) 2024.10.17
'1️⃣ 백앤드/이펙티브 자바' 카테고리의 다른 글
  • [아이템29] 이왕이면 제네릭 타입으로 만들라
  • [아이템28] 배열보다는 리스트를 사용하라
  • [아이템26] 로 타입은 사용하지 말라
  • [아이템25] 톱레벨 클래스는 한 파일에 하나만 담으라
HOZINU
HOZINU
주니어 백앤드 개발자의 세상만사 이모저모. 주로 개발 이야기를 다룸.
  • HOZINU
    백엔드 탐험 일지
    HOZINU
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • ⛪ HOME
    • 🌍 GITHUB
    • 카테고리 (73)
      • 1️⃣ 백앤드 (72)
        • 이펙티브 자바 (72)
      • 2️⃣ CS (0)
        • 운영체제 (0)
        • 네트워크 기초 (0)
        • 네트워크 응용 (0)
        • SSL & PKI (0)
        • 기타 (0)
      • 3️⃣ 코딩테스트 (0)
      • 4️⃣ 개인공부 (0)
        • MSA (0)
        • REDIS (0)
      • 5️⃣ 일상이야기 (1)
  • 인기 글

  • 태그

    표준예외
    싱글턴
    hashcode
    정보은닉
    try-with-resources
    맥북
    캡슐화
    빌더
    optional
    equals
    finalizer
    CLONE
    Cleaner
    Comparable
    정적 팩터리 메서드
    로타입
    의존객체
    계층구조
    컴포지션
    멤버클래스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
HOZINU
[아이템27] 비검사 경고를 제거하라
상단으로

티스토리툴바