<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          java 中協(xié)變,逆變,不變簡單理解

          共 4402字,需瀏覽 9分鐘

           ·

          2023-08-23 14:44

          1. 什么是協(xié)變、逆變、不變

          假設有兩個類,Dog和Animal,如果用Dog <= Animal 表示它倆的繼承關系。用f(type) 表示類型構(gòu)造器,一個已知的類型被類型構(gòu)造器處理后就是一個嶄新的類型。


          協(xié)變就是f(Dog)是f(Animal)的子類,即f(Dog) <= f(Animal);逆變就是f(Animal)是f(Dog)的子類,即f(Aniaml) <= f(Dog);不變就是指f(Dog)與f(Animal)之間沒有關系


          型構(gòu)造器可以是泛型 List<Animal> , 可以是數(shù)組  Animal[] ,可以是函數(shù)方法  method(Animal)

          2. java 泛型和數(shù)組

          • ? java泛型不支持逆變和協(xié)變,只能是不變

               List<Animal> animals = new ArrayList<Dog>(); // 編譯錯誤,java泛型不支持逆變和協(xié)變,只能是不變
            
          • ? java數(shù)組支持協(xié)變,不支持逆變,但也正因為支持協(xié)變,數(shù)組可能踩坑

               Animal[] animals = new Dog[10];
           animals[0] = new Dog();
           animals[1] = new Cat(); // 運行時異常 java.lang.ArrayStoreException

          3. java 泛型協(xié)變&上界

          • ? 考慮泛型支持協(xié)變后有什么好處,解決了什么問題?

                  // processAnimals方法中如果不支持泛型協(xié)變,那么難道要通過接收類型的不同重寫好多的方法嗎?太麻煩了!!!
              public static void main(String[] args) {
              processAnimals(new ArrayList<Cat>()); // 編譯錯誤
              proceessAimals(new ArrayList<Dog>()); // 編譯錯誤
              }
               public static void processAnimals(List<Animal> animals) {
              // ...
              }
          • ? 在java泛型中加入extends關鍵字實現(xiàn)支持協(xié)變,<? extends Animal> 其中?代表不確定類型通配符,和extends結(jié)合就聲明了泛型的上限,表示接收的類型只能是指定類型或是該類型的子類

          • ? 上面說數(shù)組支持協(xié)變,添加其他類型會出現(xiàn)運行時異常,泛型協(xié)變?yōu)榱硕沤^這種隱患,所以泛型協(xié)變除了null 可以寫,其他的都不能寫(編譯異常),可以讀

          • ? 指定上界的好處,限定類型(編譯錯誤提醒);可以訪問上界類型中的方法(要不只能訪問Object類中方法)

                  // 使用extends關鍵字讓泛型支持協(xié)變,這樣processAniamls方法中的泛型變量就能接收子類集合了
              public static void processAnimals(List<> extends Animal> anumals){
              
              }
              
              public static void processAnimalsExtends(List<? extends Animal> animals) {
                  animals.add(null); // 正常
                  /**
                   * 協(xié)變不允許傳入除null
                   */

                  // animals.add(new Animal()); // 編譯錯誤
                  // animals.add(new Dog()); // 編譯錯誤
                  animals.remove(new Dog()); // 不會破壞類型安全
                  animals.contains(new Dog()); // 不會破壞類型安全
              }

              public class AKA<T extends Animal>{

                  public static void main(String[] args) {
                  AKA<Animal> animalAKA = new AKA<>();
                  AKA<Cat> catAKA = new AKA<>();
                  AKA<String> stringAKA = new AKA<String>();// 編譯錯誤
              }
          }

          4.java 泛型逆變&下界

          • ? 使用super關鍵字聲明泛型下界,如<? super Dog>,逆變后就可以接收本類型或父類型的泛型類

          • 逆變可以添加元素,逆變泛型可以接受本類型及父類型元素,但是添加元素只能添加指定類型或指定類型的子類

                  public static void testDog(List<? super Dog> dest,list<? extends Dog> src){
                  for(Dog dog :src){
                  if(dog.isHappy()){
                   dest.add(dog);
                  }
                  }
              }
              
              public static void main(Stringp[] args){
              testDog(new ArrayList<Animal>(),new ArrayList<哈士奇>()); // 正確
              }

          5.應用場景

          • ? 只讀不寫:用協(xié)變

          • ? 只寫不讀:用逆變

          • ? 又讀又寫:用不變

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩无码 国产精品 | 成人精品秘 免费 | 黄色欧美视频网站 | 中国一级黄色视频勉费看 | 91在线无码精品秘 豆花 |