본문 바로가기

JAVA/Effective Java

item 27) 비검사 경고를 제거하라

728x90

0. 제네릭의 장점

  • 컴파일 시 강한 타입 체크를 할 수 있습니다.
    자바 컴파일러 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대한 강한 타입 체크를 합니다. 실행 시 타입 에러가 나는 것보다는 컴파일 시에 미리 타입을 강하게 체크해서 에러를 사전에 방지하는 것이 좋습니다.

  • 타입 변환을 제거합니다.
    비제네릭 코드는 불필요한 타입 변환을 하기 때문에 프로그램 성능에 악영향을 미칩니다. 다음 아래 코드를 보면 List에 문자열 요소를 저장했지만, 요소를 찾아올 때는 반드시 String으로 타입 변환을 해야합니다.

List list = new ArrayList();
list.add("hello");
String str = (String) list.get(0); //타입 변환 필요

List<String> list = new ArrayList<String>();
list.add("hello");
String str = list.get(0); // 타입 변환을 하지 않습니다.

1. 비검사 경고 (warning : [unchecked])

 

- 타입변환할때 타입 체크를 검사 안 했다는 경고

Set set = new HashSet();
      /*
      	uses unchecked or unsafe operations.
		Note: Recompile with -Xlint:unchecked for details. 경고 발생
      */
      
Set <String> set = new HashSet<>();

위의 코드는 제너릭을 사용했는데 타입체크를 안해서 나온 경고다.

이 경고는 자바7 부터 제공하는 다이아몬드 연산자  <> 를 사용하면 쉽게 제거할 수 있다.

컴파일러는 양쪽을 보고 한쪽의 타입을 추론하게 됩니다. (이쪽의 경우는 왼쪽을 가지고 오른쪽을 추론함)

 

 

 

2. 할수 있는 한 모든 비검사 경고를 제거하라.

 

  • 타입 안전성 보장(ClassCastException 발생 X)
  • 경고를 제거할수는 없지만 타입안전이 확신할수 있다면 @SuppressWarnings("unchecked") 어노테이션을 달아 경고를 숨긴다.
  • 이 때 가능한 좁은 범위에 어노테이션을 적용하다.
  • @SuppressWarnings("unchecked") 어노테이션을 사용할때 그 경고를 무시해도 안전한 이유를 주석으로 남겨야 한다.

 

public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            /*  unchecked 발생 */

            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
            
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }
    
    
    /*    @SuppressWarnings 는 선언부에만 사용 가능 ! 
    메소드전체에 붙이기보다는 정말 필요한 최소의 범위에만 사용하자.
    */

  public <T> T[] toArray(T[] a) {
        if (a.length < size){
            // Make a new array of a's runtime type, but my contents:
            @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;
    }