> Java > java지도 시간 > Java에서 확장 T와 슈퍼 T는 무엇입니까?

Java에서 확장 T와 슈퍼 T는 무엇입니까?

PHPz
풀어 주다: 2023-05-09 11:19:17
앞으로
1321명이 탐색했습니다.

? 와일드카드 유형

  • >는 유형의 상한을 나타내며, 이는 매개변수화된 유형이 T 또는 T의 하위 클래스일 수 있음을 나타냅니다. 유형(Java Core에서는 슈퍼 유형 한정이라고 함)은 Object;

  • upperbound

  • 예를 들어, 이제 다음을 정의합니다: List
    import java.util.LinkedList;
    import java.util.List;
    
    public class test {
        public static void main(String[] args) {
            List<? extends Father> list = new LinkedList<>();
            list.add(new Son());
        }
    }
    class Human{
    }
    class Father extends Human{
    }
    class Son extends Father{
    }
    class LeiFeng extends Father {
    }
    로그인 후 복사

    list.add(new Son()) 이 줄은 오류를 보고합니다. put(Son)이 정의되지 않았습니다. List

    List

    다음을 시도해 볼 수 있습니다:

    List<? extends Father> list = new LinkedList<Son>();
    list.add(new Son());
    로그인 후 복사

    Son 유형을 지정하더라도 add 메소드를 사용하여 Son 객체를 추가할 수 없습니다.

    Father 클래스와 Father 클래스의 하위 클래스를 목록에 추가할 수 없는 이유는 무엇입니까?

    List는 다음 할당이 허용됨을 의미합니다.

       List<? extends Father> list1 = new ArrayList<Father>();
       List<? extends Father> list2 = new ArrayList<Son>();
       List<? extends Father> list3 = new ArrayList<LeiFeng>();
    로그인 후 복사

    List가 추가 방법을 지원하면

    list1은 Father와 모든 하위 클래스를 추가할 수 있습니다.

    • list2는 Son과 Son의 모든 하위 클래스를 추가할 수 있습니다.

    • list3은 LeiFeng과 LeiFeng의 모든 하위 클래스를 추가할 수 있습니다.

    • 다음 코드는 컴파일에 실패합니다.

      list1.add(new Father());//error
      list1.add(new Son());//error
      로그인 후 복사
    • 그 이유는 컴파일러는 컨테이너가 Father 또는 그 파생 클래스라는 것만 알지만 특정 유형은 알지 못하기 때문입니다. 혹시 아버지? 어쩌면 아들? 어쩌면 LeiFeng, XiaoMing? 나중에 할당에 Father가 사용된다는 사실을 컴파일러가 확인한 후에는 컬렉션의 매개 변수 유형이 "Father"로 제한되지 않습니다. 대신에 자리 표시자 CAP#1이 표시되어 Father 또는 Father의 하위 클래스를 캡처함을 나타냅니다. 특정 클래스는 모르지만 코드는 CAP#1입니다. 그러면 Son, LeiFeng 또는 Father 컴파일러를 삽입하려는 경우 이 CAP#1과 일치할 수 있는지 알 수 없으므로 허용하지 않습니다.

    따라서 와일드카드 문자 와 유형 매개변수의 차이점은 컴파일러에게는 모든 T가 동일한 유형을 나타낸다는 것입니다. 예를 들어 다음 일반 메서드에서 세 개의 T는 모두 동일한 유형(String 또는 Integer)을 나타냅니다.

    public <T> List<T> fill(T... t);
    로그인 후 복사

    하지만 와일드카드 문자 에는 그러한 제약이 없습니다. List는 단순히 컬렉션에 뭔가가 있는데 그것이 무엇인지 모릅니다.

    여기서 오류는 List에 아무것도 넣을 수 없다는 것입니다.

    List 목록은 추가할 수 없지만 이 형식은 여전히 ​​매우 유용합니다. add 메소드를 사용할 수는 없지만 초기화 중에 Season이 다른 유형을 지정할 수 있습니다. 예:

    List<? extends Father> list1 = getFatherList();//getFatherList方法会返回一个Father的子类的list
    로그인 후 복사

    또한 Father 클래스 또는 해당 하위 클래스 중 하나가 목록에 저장되어 있으므로 get 메소드를 사용하여 값을 직접 얻을 수 있습니다.

    List<? extends Father> list1 = new ArrayList<>();
    Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
    Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
    Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
    Son son = (Son)list1.get(0);
    로그인 후 복사

    Lowerbound < super T> ; 과거에는 영향을 미치지 않습니다. 내부에 저장되지만 꺼낼 때만 Object 객체에 배치할 수 있습니다. 하한은 super로 선언됩니다. 이는 매개변수화된 유형이 지정된 유형이거나 상위 유형일 수 있음을 의미합니다. 이 유형은 Object까지입니다.

    //super只能添加Father和Father的子类,不能添加Father的父类,读取出来的东西只能存放在Object类里
    List<? super Father> list = new ArrayList<>();
    list.add(new Father());
    list.add(new Human());//compile error 
    list.add(new Son());
    Father person1 = list.get(0);//compile error 
    Son son = list.get(0);//compile error 
    Object object1 = list.get(0);
    로그인 후 복사

    하한은 요소의 최소 세분성의 하한을 지정하기 때문에 실제로 컨테이너 요소의 유형 제어를 완화합니다. 요소는 Father의 기본 클래스이므로 Father보다 작은 단위로 저장될 수 있습니다. 유형 안전상의 이유로 Father 객체나 그 하위 클래스(예: Son) 객체를 추가할 수 있지만 컴파일러는 List의 내용이 Father의 어떤 슈퍼클래스인지 모르기 때문에 특정 슈퍼클래스를 추가하는 것이 허용되지 않습니다. 클래스(예: 인간). 그리고 우리가 이를 읽을 때 컴파일러는 그것이 어떤 유형인지 알지 못한 채 Object 객체만 반환할 수 있습니다. 왜냐하면 Object는 모든 Java 클래스의 궁극적인 조상 클래스이기 때문입니다. 하지만 이 경우 요소의 모든 유형 정보가 손실됩니다.

    PECS 원리

    마지막으로 PECS(Producer Extends Consumer Super) 원리가 무엇인지 살펴보겠습니다. 이미 잘 이해되어 있습니다.

    외부에서 콘텐츠를 자주 읽는다면, 상한 확장.

      자주 꽂는다면 네더슈퍼가 적합합니다.

    위 내용은 Java에서 확장 T와 슈퍼 T는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿