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

무한성장개발자·2024년 10월 20일

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

package me.whiteship.chapter05.item27.unchecked;

import java.util.HashSet;
import java.util.Set;

public class SetExample {

    public static void main(String[] args) {
        Set names = new HashSet();

         Set<String> strings = new HashSet();
    }
}

로타입을 사용했다는 뜻

package me.whiteship.chapter05.item27.unchecked;

import java.util.HashSet;
import java.util.Set;

public class SetExample {

    public static void main(String[] args) {
        Set<Integer> names = new HashSet<>();

        Set<String> strings = new HashSet();
    }
}

<> 다이아몬드 연산자를 사용하면 앞의 타입을 안 적어줘도 된다. 알아서 추론을 한다.

package me.whiteship.chapter05.item27.unchecked;

import java.util.HashSet;
import java.util.Set;

public class SetExample {

    public static void main(String[] args) {
        Set names = new HashSet();

        Set<String> strings = new HashSet<>();
    }
}

아래것도 <>를 쓰면 경고가 사라진다.

SuppressWarnings

package me.whiteship.chapter05.item27.suppress;

import java.util.Arrays;

public class ListExample {

    private int size;

    Object[] elements;

    public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            /**
             * 이 애노테이션을 왜 여기서 선언했는지..
             */
            
            return (T[]) Arrays.copyOf(elements, size, a.getClass());
        }
        System.arraycopy(elements, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

}

SuppressWarnings같은 경우 우리가 타입 안정성을 어떻게 여기서 보장할 수 있는 방법은 없지만 실질적으로 타입이 안전한다.

엘리먼트가 T랑 같은 타입이다. 내가 작성한 코드는 어떻게든지 엘리먼트에는 무조건 T타입과 호환되는 타입만 들어오게 된다.

경고자체를 무시해준다. 이 부분에 대한 경고를 알고 있으니까 해당 예외를 무시한다.
supress하지 않으면 해당 부분이외에 뭔가 좀 다른 곳에서 다른 문제가 발생했나 보구나 라고 알 수 있다.
return문에는 supresswarning을 못 붙이기 때문에 변수로 만들어준다.

타입이 동일한데 비검사 경고를 없앨 수 없는 경우 surpresswarning을 붙인다.

package me.whiteship.chapter05.item27.suppress;

import java.util.Arrays;

public class ListExample {

    private int size;

    Object[] elements;

    public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            /**
             * 이 애노테이션을 왜 여기서 선언했는지..
             */
            @SuppressWarnings("unchecked")
            T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
            return result;
        }
        System.arraycopy(elements, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

}

가능한한 좁은 범위에 정의해야 한다.
메소드 전체 범위에서 감추면 System.arraycopy(elements, 0, a, 0, size);에서 발생하는 경고가 무시가 된다.
그래서 그 위에 주석도 적어준다.

아이템 27. 완벽 공략 - 애너테이션

package me.whiteship.chapter05.item27.annotation;

import java.util.Arrays;

@MyAnnotation
public class MyClass {

    @MyAnnotation
    public static void main(String[] args) {
        Arrays.stream(MyClass.class.getAnnotations()).forEach(System.out::println);
    }
}

@Documented : Javadoc을 만들 때 애노테이션 정보가 자바독에 포함된다.
@Rentension : 애노테이션에 대한 정보를 언제까지 참조할 수 있게끔 할 것이냐?
RetentionPolicy.RUNTIME : 애노테이션을 사용한 코드에서 이 애노테이션에 대한 정보를 런타임 중에도 이용할 수 있게끔 하는 것이다.

RetentionPolicy.CLASS : 클래스 파일에서까지만 참조 가능하고 Runtime에서는 안된다.

RetentionPolicy.SOURCE : 주석같이 사용한다. 바이트코드에서도 사용할 수 없다. 컴파일 할 때만 사용이 된다. 그 이후에는 의미가 없다.

ElementType.Target : 이 애노테이션을 어디서 사용할 수 있느냐?
ElementType.TYPE : Type에다 선언하는 거고, 메소드 위에 다가는 안된다. 변수 위에다가도 안된다.
ElementType.METHOD : 메소드에 추가할 수 있게 된다.
ElementType.LOCAL_VARIABLE : 지역 변수 변수 선언을 의미한다.
ElementType.MODULE : 자바 모듈을 말하는 것이다.

0개의 댓글