[범 형]범 형 사용 시 주의사항

5863 단어 범 형Java se
자바 에서 범 형 을 효과적으로 사용 하려 면 다음 과 같은 제한 에 주의해 야 합 니 다.
원본 데이터 형식 을 사용 할 수 없습니다.
아래 의 범 형 류 를 고려 하 다.
class Pair<K, V> {

    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    // ...
}

Pair 대상 을 만 들 때 형식 매개 변수 K 와 V 는 원본 데이터 형식 일 수 없습니다.
Pair<int, char> p = new Pair<>(8, 'a');  //     

형식 매개 변수 K 와 V 는 비원 초적 인 데이터 형식 만 사용 할 수 있 습 니 다.
Pair<Integer, Character> p = new Pair<>(8, 'a');

자바 컴 파 일 러 는 아래 와 같이 Integer.valueOf(8)를 사용 하여 8 을 자동 으로 봉 하고 Character('a')를 사용 하여'a'를 자동 으로 봉 합 니 다.
Pair<Integer, Character> p = new Pair<>(Integer.valueOf(8), new Character('a'));

형식 매개 변수 인 스 턴 스 를 만 들 수 없습니다.
형식 매개 변수의 인 스 턴 스 를 만 들 수 없습니다.다음 코드 에 컴 파일 오류 가 발생 할 수 있 습 니 다.
public static <E> void append(List<E> list) {
    E elem = new E();  // compile-time error
    list.add(elem);
}

이 문 제 를 피하 기 위해 서 당신 은 반사 체 제 를 사용 할 수 있 습 니 다.
public static <E> void append(List<E> list, Class<E> cls) throws Exception {
    E elem = cls.newInstance();   // OK
    list.add(elem);
}

현재 아래 코드 처럼 append 방법 을 호출 할 수 있 습 니 다.
List<String> ls = new ArrayList<>();
append(ls, String.class);

형식 매개 변 수 를 사용 하여 정적 속성 을 설명 할 수 없습니다.
클래스 의 정적 속성 은 클래스 등급 의 변수 로 모든 비 정적 대상 에 의 해 공 유 됩 니 다.따라서 형식 매개 변 수 를 사용 하여 정적 속성 을 설명 할 수 없습니다.
다음 코드 를 고려 하 십시오:
public class MobileDevice<T> {
    private static T os;

    // ...
}

형식 매개 변수 가 정적 속성 을 설명 할 수 있 도록 허용 하면 다음 코드 는 혼 란 스 러 울 것 입 니 다.
MobileDevice<Smartphone> phone = new MobileDevice<>();
MobileDevice<Pager> pager = new MobileDevice<>();
MobileDevice<TabletPC> pc = new MobileDevice<>();

정적 속성 os 가 동시에 phone,pager,pc 와 공유 되 기 때문에 현재 os 의 실제 유형 은 무엇 입 니까?스마트 폰,Pager,태 블 릿 PC 타 입 을 동시에 사용 할 수 는 없다.따라서 정적 인 형식 매개 변수 속성 을 설명 할 수 없습니다.
일반 클래스 에 강제 형식 변환 과 instanceof 를 사용 할 수 없습니다.
자바 컴 파 일 러 는 컴 파 일 러 기간 에 모든 범 형 에 대해 형식 제거 작업 을 하기 때문에 실행 할 때 어떤 종류의 형식 파 라미 터 를 사용 하 는 지 확인 할 수 없습니다.
public static <E> void rtti(List<E> list) {
    if (list instanceof ArrayList<Integer>) {  //     
        // ...
    }
}

rtti 방법 에 전 달 된 list 매개 변수 의 값 은 다음 과 같 습 니 다.
{ ArrayList<Integer>, ArrayList<String> LinkedList<Character>, ... }

실행 할 때 형식 인 자 를 추적 하지 않 기 때문에 Array List와 Array List의 차이 점 을 구분 할 수 없습니다.가장 많이 할 수 있 는 것 은 무제 한 마스크 를 사용 하여 형식 이 Array List 인지 확인 하 는 것 입 니 다.
public static void rtti(List<?> list) {
    if (list instanceof ArrayList<?>) {  // OK; instanceof requires a reifiable type
        // ...
    }
}

일반적인 상황 에서 무제 한 마스크 를 사용 하지 않 으 면 범 형 류 는 유형 강제 변환 을 할 수 없습니다.
List<Integer> li = new ArrayList<>();
List<Number>  ln = (List<Number>) li;  //     

그러나 가끔 은 컴 파일 러 가 유형 매개 변수 가 정확 하 다 는 것 을 확인 할 수 있 는 상황 에서 유형 강제 전환 을 할 수 있다.
List<String> l1 = ...;
ArrayList<String> l2 = (ArrayList<String>)l1;  // OK

일반 클래스 의 배열 을 만 들 수 없습니다.
일반적인 배열 을 만 들 수 없습니다.예 를 들 어 아래 코드 는 컴 파일 을 통 해 만 들 수 없습니다.
List<Integer>[] arrayOfLists = new List<Integer>[2];  //     

다음 코드 는 왜 이 오류 가 발생 했 는 지 보 여 줍 니 다.
Object[] strings = new String[2];
strings[0] = "hi";   // OK
strings[1] = 100;    // An ArrayStoreException is thrown.

그렇다면 범 형 클래스 List 의 배열 이 라면 이 문제 도 있 을 것 이다.
Object[] stringLists = new List<String>[];  //     ,           
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown

형식 매개 변 수 를 만 들 거나 캡 처 하거나 던 질 수 없 는 대상
일반적인 클래스 는 Throwable 클래스 를 직접 또는 간접 적 으로 계승 할 수 없습니다.예 를 들 어 아래 코드 는 컴 파일 할 수 없습니다.
class MathException<T> extends Exception { /* ... */ }    //     

class QueueFullException<T> extends Throwable { /* ... */ //     

방법 에서 도 유형 매개 변수 이상 을 포착 할 수 없습니다:
public static <T extends Exception, J> void execute(List<J> jobs) {
    try {
        for (J job : jobs)
            // ...
    } catch (T e) {   //     
        // ...
    }
}

유일 하 게 할 수 있 는 것 은 형식 매개 변 수 를 방법의 throws 뒤에 두 는 것 입 니 다.
class Parser<T extends Exception> {
    public void parse(File file) throws T {     // OK
        // ...
    }
}

형식 매개 변수 만 다른 상황 에서 방법 으로 다시 불 러 오 는 것 을 허용 하지 않 습 니 다.
다음 과 같은 쓰 기 는 컴 파일 오류 가 발생 할 것 입 니 다.
public class Example {
    public void print(Set<String> strSet) { }
    public void print(Set<Integer> intSet) { }
}

글 의 출처:
http://www.aptusource.org/2014/04/restrictions-on-generics/

좋은 웹페이지 즐겨찾기