제네릭은 컴파일러의 경고를 많이 보게되는 기능 중 하나입니다.
무점검 형변환 경고(uncecked warning), 무점검 메소드 호출 경고(unchecked method invocation warning), 무점검 제네릭 배열 생성 경고 등
밑의 코드를 한번 볼까요
컴파일러 상 에러는 나지 않았지만 Unchecked assignment로 경고를 주고 있습니다.
저번 포스트에서도 봤던 거죠.
밑의 코드대로 바꾸면 경고는 사라집니다.
Set<String> exaltation = new HashSet<String>():
이 경고는 간단하게 제거가 가능했지만
제네릭은 경고가 나오기 쉬운만큼 지우기 어려운 경고들도 많습니다.
만약 형 안정성이 확실한데 경고를 지우기 어렵다면
어노테이션을 사용하는 방법이 있습니다.
ArrayList의 일부인 toArray를 예로 들 것인데, 먼저 toArray 메소드의 역할을 알아봅시다.
public static void main(String[] args) {
List<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2);
intList.add(3);
Integer[] intArray = intList.toArray(new Integer[0]);
System.out.println(intArray.length);
}
간단하게 작생해봤는데
toArray는 리스트를 Array리스트로 바꾸어주는 역할을 하는 메소드입니다.
new Integer[?] 의 부분이 0일 경우 결과는 3
new Integer[?] 의 부분이 5일 경우 결과는 5
가 핵심입니다. 즉 매개변수로 들어온 배열의 사이즈가 리스트의 크기보다 작으면
리스트의 크기로 사용, 매개변수로 들어온 배열의 사이즈가 리스트보다 크면 배열의 사이즈를 사용합니다.
그럼 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;
}
내부는 이렇게 되어있습니다.
사이즈를 기준으로 데이터를 복사하게끔 제네릭으로 설계되어있죠.
하지만 이 코드는 아래와 같이 경고가 뜹니다.
unchecked 경고입니다.
ArrayList에서 인자를 받을 때 이 경고가 걱정하는 바는 해결이 되기 때문에
이 경고는 억제하는 것이 좋습니다.
public <T> T[] toArray(T[] a) {
if (a.length < size){
@SupressWarnings("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는 강제적으로 경고를 사라지게 만드는 만큼
사용할 때마다 관련 코드가 왜 형안정성을 위반하지 않는지 주석을 남기는 것이 좋습니다.
'프로그래밍 > Java' 카테고리의 다른 글
이펙티브 자바 규칙 25 - 배열 대신 리스트를 써라 (0) | 2018.03.22 |
---|---|
이펙티브 자바 규칙 23 - 새 코드에는 무이자 제네릭 자료형을 사용하지 마라 (0) | 2018.03.08 |
이펙티브 자바 규칙 22 - 내부클래스 종류와 멤버 클래스는 가능하면 static으로 (0) | 2018.03.05 |