자바 기반 자바 범 형 어댑터 상세 설명

머리말
자바 범 형(generics)은 JDK 5 에 도 입 된 새로운 기능 으로 범 형 은 컴 파일 시 유형 보안 검색 체 제 를 제공 합 니 다.이 기 제 는 개발 자가 컴 파일 할 때 불법 유형 을 감지 할 수 있 도록 합 니 다.
범 형의 본질은 매개 변수 화 유형 이다.즉,조작 한 데이터 형식 이 하나의 매개 변수 로 지정 되 었 다 는 것 이다.
범 형 이 가 져 온 이점
범 형 이 없 는 상황 에서 유형 Object 에 대한 인용 을 통 해 매개 변수의'임 의 화'를 실현 하고'임 의 화'가 가 져 온 단점 은 명시 적 강제 유형 전환 을 해 야 한 다 는 것 이다.이런 전환 은 개발 자가 실제 매개 변수 유형 을 예지 할 수 있 도록 요구 하 는 상황 에서 이 루어 진 것 이다.강제 형식 변환 오류 의 경우 컴 파일 러 가 오 류 를 알 리 지 않 고 실행 할 때 만 이상 이 발생 할 수 있 습 니 다.이것 은 그 자체 가 안전 위험 입 니 다.
그러면 일반적인 장점 은 컴 파일 할 때 유형 안전 을 검사 할 수 있 고 모든 강제 전환 은 자동 과 암시 적 인 것 이다.

public class GlmapperGeneric<T> {
        private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }

    public static void main(String[] args) {
        // do nothing
    }

  /**
    *      
    */
  public void noSpecifyType(){
    GlmapperGeneric glmapperGeneric = new GlmapperGeneric();
    glmapperGeneric.set("test");
    //         
    String test = (String) glmapperGeneric.get();
    System.out.println(test);
  }

  /**
    *     
    */
  public void specifyType(){
    GlmapperGeneric<String> glmapperGeneric = new GlmapperGeneric();
    glmapperGeneric.set("test");
    //          
    String test = glmapperGeneric.get();
    System.out.println(test);
  }
}
위의 코드 에 있 는 specify Type 방법 은 강제 변환 을 줄 이 고 컴 파일 할 때 유형 안전 을 검사 할 수 있 으 며 클래스,방법,인터페이스 에 사용 할 수 있 습 니 다.
범용 어댑터
우 리 는 범 형 류,범 형 방법,범 형 인 터 페 이 스 를 정의 할 때 자주 서로 다른 어댑터 를 만 날 수 있다.예 를 들 어 T,E,K,V 등 이다.이런 어댑터 는 무슨 뜻 일 까?
자주 쓰 는 T,E,K,V?
본질 적 으로 이런 것들 은 모두 어댑터 로 별 차이 가 없 으 며,단지 인 코딩 할 때의 약 속 된 것 에 불과 하 다.예 를 들 어 상기 코드 중의 T 는 A-Z 사이 의 모든 자모 로 바 꿀 수 있 고 프로그램의 정상 적 인 운행 에 영향 을 주지 않 지만 T 대신 다른 자모 로 바 꾸 면 가 독성 이 약 할 수 있다.보통 T,E,K,V?이렇게 약 속 했 습 니 다.
  • ?불확실 한 자바 유형
    T(type)는 구체 적 인 자바 유형 을 나타 낸다
  • K V(key value)는 각각 자바 키 의 Key Value 를 나타 낸다
  • E(element)대표 Element?무한 어댑터
    먼저 작은 예 에서 볼 때 원문 은 여기에 있다.
    저 는 아버지 류 Animal 과 몇 개의 자 류 를 가지 고 있 습 니 다.예 를 들 어 개,고양이 등 이 있 습 니 다.지금 은 동물 의 목록 이 필요 합 니 다.제 첫 번 째 생각 은 다음 과 같 습 니 다.
    
    List<Animal> listAnimals
    하지만 사장 님 의 생각 은 그렇습니다.
    
    List<? extends Animal> listAnimals
    왜 간단 한 범 형 이 아 닌 마스크 를 사용 합 니까?어댑터 는 사실 국부 변 수 를 설명 할 때 아무런 의미 가 없 지만,하나의 방법 으로 매개 변 수 를 설명 할 때 매우 중요 하 다.
    
    static int countLegs (List<? extends Animal > animals ) {
        int retVal = 0;
        for ( Animal animal : animals )
        {
            retVal += animal.countLegs();
        }
        return retVal;
    }
    
    static int countLegs1 (List< Animal > animals ){
        int retVal = 0;
        for ( Animal animal : animals )
        {
            retVal += animal.countLegs();
        }
        return retVal;
    }
    
    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
         //     
        countLegs( dogs );
        //   
        countLegs1(dogs);
    }
    countLegs 1 을 호출 하면 빨간색 으로 표 시 됩 니 다.잘못된 정 보 는 다음 과 같 습 니 다.

    따라서 불확실 하거나 실제 조작 에 관심 이 없 는 유형 에 대해 서 는 무제 한 마스크(괄호 안의 물음표,즉)를 사용 하여 모든 유형 을 가 질 수 있다 는 것 을 표시 할 수 있다.countLegs 방법 에 서 는 지난 회 를 한정 하 였 으 나 구체 적 인 유형 이 무엇 인지 에 관심 이 없 기 때문에 들 어 오 는 Animal 의 모든 하위 클래스 를 지원 할 수 있 고 잘못 보고 하지 않 습 니 다.countLegs 1 은 안 돼.
    상계 어댑터
    지난번:extends 키워드 로 매개 변수 화 된 유형 이 지정 한 유형 이나 이 유형의 하위 클래스 일 수 있 음 을 표시 합 니 다.
    유형 매개 변수 에서 extends 를 사용 하면 이 범 형 중의 매개 변 수 는 반드시 E 또는 E 의 하위 클래스 여야 한 다 는 것 을 나타 낸다.그러면 두 가지 장점 이 있다.
  • 들 어 오 는 유형 이 E 또는 E 의 하위 클래스 가 아니라면 컴 파일 에 성공 하지 못 합 니 다
  • 범 형 에서 E 를 사용 할 수 있 는 방법,그렇지 않 으 면 E 로 강하 게 전환 해 야 사용 할 수 있다
  • 
    private <K extends A, E extends B> E test(K arg1, E arg2){
        E result = arg2;
        arg2.compareTo(arg1);
        //.....
        return result;
    }
    형식 매개 변수 목록 에 여러 종류의 매개 변수 상한 선 이 있 으 면 쉼표 로 구분 합 니 다.
    하계 어댑터
    하계:슈퍼 로 설명 합 니 다.매개 변수 화 된 형식 이 지정 한 형식 일 수도 있 고,이 유형의 부모 형식 일 수도 있 습 니 다.Object 까지.
    형식 매개 변수 에서 슈퍼 를 사용 하면 이 일반적인 매개 변 수 는 E 나 E 의 부모 클래스 여야 합 니 다.
    
    private <T> void test(List<? super T> dst, List<T> src){
        for (T t : src) {
            dst.add(t);
        }
    }
    
    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
        List<Animal> animals = new ArrayList<>();
        new Test3().test(animals,dogs);
    }
    // Dog   Animal    
    class Dog extends Animal {
    
    }
    dst 유형 은 src 보다 크 고 같은 유형 입 니 다.여기 의'큰 것 과 같은 것'은 dst 가 표시 하 는 범위 가 src 보다 넓 기 때문에 dst 를 담 을 수 있 는 용기 도 src 를 담 을 수 있 습 니 다.
    상계 어댑터 는 주로 데 이 터 를 읽 는 데 사용 되 고,하계 어댑터 는 주로 데 이 터 를 쓰 는 데 쓰 인 다.
    ?T 와 의 차이

    ?T 와 모두 불확실 성 을 나타 내 는 유형 은 우리 가 T 를 조작 할 수 있다 는 것 과 차이 가 있 지만 그렇지?안 됩 니 다.예 를 들 어 다음 과 같 습 니 다.
    
    //   
    T t = operate();
    
    //    
    ?car = operate();
    간단하게 요약 하면:
    T 는 확실한 유형 으로 보통 범 형 류 와 범 형 방법의 정의 에 사 용 됩 니 다.?불확실 한 유형 으로 일반적인 방법 에 사용 되 는 호출 코드 와 형 삼 은 클래스 와 범 형 방법 을 정의 하 는 데 사용 할 수 없습니다.
    구별 1:T 를 통 해 범 형 매개 변수의 일치 성 을 확보한다.
    
    //    T              
    public <T extends Number> void
    test(List<T> dest, List<T> src)
    
    //         ,             List          
    public void
    test(List<? extends Number> dest, List<? extends Number> src)
    아래 코드 와 같이 약 정 된 T 는 Number 의 하위 클래스 여야 하지만 설명 할 때 는 String 을 사용 하기 때문에 빨간색 으로 잘못 보고 합 니 다.

    두 List 가 같은 요소 유형 을 가지 고 있다 는 것 을 보증 할 수 없습니다.
    
    GlmapperGeneric<String> glmapperGeneric = new GlmapperGeneric<>();
    List<String> dest = new ArrayList<>();
    List<Number> src = new ArrayList<>();
    glmapperGeneric.testNon(dest,src);
    위의 코드 는 컴 파일 러 에서 잘못 보고 되 지 않 지만 testnon 방법 내부 작업 에 들 어 갈 때(예 를 들 어 할당)dest 와 src 에 있어 서 유형 전환 이 필요 합 니 다.
    차이 2:유형 매개 변 수 는 다 중 한정 이 가능 하지만 어댑터 는 안 됩 니 다.

    &기 호 를 사용 하여 다 중 경계(Multi Bounds)를 설정 합 니 다.일반적인 유형 T 는 MultiLimitInterfaceA 와 MultiLimitInterfaceB 의 공유 하위 유형 이 어야 합 니 다.이때 변수 t 는 모든 한 정 된 방법 과 속성 을 가지 게 됩 니 다.어댑터 에 있어 서 는 정확 한 유형 이 아니 기 때문에 다 중 제한 을 할 수 없습니다.
    구별 3:마스크 는 초 클래스 한정 을 사용 할 수 있 지만 유형 매개 변 수 는 안 됩 니 다.
    유형 매개 변수 T 는 하나의 유형 한정 방식 만 가지 고 있 습 니 다.
    
    T extends A
    근 데 마스크?두 가지 한정 을 진행 할 수 있 습 니 다.
    
    ? extends A
    ? super A
    `Class`와`Class`의 구별
    앞 에 소 개 했 어 요?T 와 의 차이 점 은Class<T><Class<?>에 대해 어떤 차이 가 있 습 니까?
    4.567914.와 4.567914.
    가장 흔히 볼 수 있 는 것 은 반사 장면 에서 사용 되 는 것 으로 발사 코드 로 설명 한다.
    
    //            multiLimit
    //   ,        ,            
    MultiLimit multiLimit = (MultiLimit)
    Class.forName("com.glmapper.bridge.boot.generic.MultiLimit").newInstance();
    상기 코드 에 대해 서 는 운행 기간 에 반 사 된 유형 이 MultiLimit 류 가 아니라면 자바.lang.ClassCastException 오 류 를 보고 할 것 입 니 다.
    이러한 상황 에 대해 서 는 다음 코드 로 대체 하여 컴 파일 기간 에 유형의 문 제 를 직접 검사 할 수 있 도록 할 수 있 습 니 다.

    4.567914.실례 화 할 때 T 는 구체 적 인 유형 으로 교체 해 야 한다Class<T>그것 은 통 배 범 형 입 니 다.?모든 유형 을 대표 할 수 있 기 때문에 성명 시의 제한 상황 에 주로 사 용 됩 니 다.예 를 들 어 우 리 는 이렇게 설명 할 수 있다.
    
    //   
    public Class<?> clazz;
    //    ,   T       
    public Class<T> clazzT;
    그래서 어떤 종류의 클 라 스 를 정 해 야 할 지 모 를 때 클 라 스 를 정의 할 수 있 습 니 다.

    그렇다면 현재 클래스 도 T 를 지정 해 야 합 니 다.
    
    public class Test3<T> {
        public Class<?> clazz;
        //     
        public Class<T> clazzT;
    자바 범 형 마스크 에 대한 자세 한 설명 은 여기까지 입 니 다.자바 범 형 마스크 에 대한 자세 한 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기