java 之泛型與可變引數詳解

wangbowj123發表於2020-12-05

1.泛型

1.1泛型概述和好處【理解】

  • 泛型概述

    ​ 是JDK5中引入的特性,它提供了編譯時型別安全檢測機制,該機制允許在編譯時檢測到非法的型別

    它的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。一提到引數,最熟悉的就是定義方法時有形參,然後呼叫此方法時傳遞實參。那麼引數化型別怎麼理解呢?顧名思義,就是將型別由原來的具體的型別引數化,然後在使用/呼叫時傳入具體的型別。這種引數型別可以用在類、方法和介面中,分別被稱為泛型類、泛型方法、泛型介面

  • 泛型定義格式

    • <型別>:指定一種型別的格式。這裡的型別可以看成是形參
    • <型別1,型別2…>:指定多種型別的格式,多種型別之間用逗號隔開。這裡的型別可以看成是形參
    • 將來具體呼叫時候給定的型別可以看成是實參,並且實參的型別只能是引用資料型別
  • 泛型的好處

    • 把執行時期的問題提前到了編譯期間
    • 避免了強制型別轉換

1.2 泛型類

  • 定義格式

    修飾符 class 類名<型別> {  }
    
  • 示例程式碼

    • 泛型類

      public class Generic<T> {
          private T t;
      
          public T getT() {
              return t;
          }
      
          public void setT(T t) {
              this.t = t;
          }
      }
      
    • 測試類

      public class GenericDemo {
          public static void main(String[] args) {
              Generic<String> g1 = new Generic<String>();
              g1.setT("林青霞");
              System.out.println(g1.getT());
      
              Generic<Integer> g2 = new Generic<Integer>();
              g2.setT(30);
              System.out.println(g2.getT());
      
              Generic<Boolean> g3 = new Generic<Boolean>();
              g3.setT(true);
              System.out.println(g3.getT());
          }
      }
      

1.3泛型方法

  • 定義格式

    修飾符 <型別> 返回值型別 方法名(型別 變數名) {  }
    
  • 示例程式碼

    • 帶有泛型方法的類

      public class Generic {
          public <T> void show(T t) {
              System.out.println(t);
          }
      }
      
    • 測試類

      public class GenericDemo {
          public static void main(String[] args) {
      		Generic g = new Generic();
              g.show("林青霞");
              g.show(30);
              g.show(true);
              g.show(12.34);
          }
      }
      

1.4泛型介面

  • 定義格式

    修飾符 interface 介面名<型別> {  }
    
  • 示例程式碼

    • 泛型介面

      public interface Generic<T> {
          void show(T t);
      }
      
    • 泛型介面實現類

      public class GenericImpl<T> implements Generic<T> {
          @Override
          public void show(T t) {
              System.out.println(t);
          }
      }
      
    • 測試類

      public class GenericDemo {
          public static void main(String[] args) {
              Generic<String> g1 = new GenericImpl<String>();
              g1.show("林青霞");
      
              Generic<Integer> g2 = new GenericImpl<Integer>();
              g2.show(30);
          }
      }
      

1.5型別萬用字元

  • 型別萬用字元的作用

    ​ 為了表示各種泛型List的父類,可以使用型別萬用字元

  • 型別萬用字元的分類

    • 型別萬用字元:<?>
      • List<?>:表示元素型別未知的List,它的元素可以匹配任何的型別
      • 這種帶萬用字元的List僅表示它是各種泛型List的父類,並不能把元素新增到其中
    • 型別萬用字元上限:<? extends 型別>
      • List<? extends Number>:它表示的型別是Number或者其子型別
    • 型別萬用字元下限:<? super 型別>
      • List<? super Number>:它表示的型別是Number或者其父型別
  • 型別萬用字元的基本使用

    public class GenericDemo {
        public static void main(String[] args) {
            //型別萬用字元:<?>
            List<?> list1 = new ArrayList<Object>();
            List<?> list2 = new ArrayList<Number>();
            List<?> list3 = new ArrayList<Integer>();
            System.out.println("--------");
    
            //型別萬用字元上限:<? extends 型別>
    //        List<? extends Number> list4 = new ArrayList<Object>();
            List<? extends Number> list5 = new ArrayList<Number>();
            List<? extends Number> list6 = new ArrayList<Integer>();
            System.out.println("--------");
    
            //型別萬用字元下限:<? super 型別>
            List<? super Number> list7 = new ArrayList<Object>();
            List<? super Number> list8 = new ArrayList<Number>();
    //        List<? super Number> list9 = new ArrayList<Integer>();
    
        }
    }
    

2.可變引數

2.1可變引數

  • 可變引數介紹

    ​ 可變引數又稱引數個數可變,用作方法的形參出現,那麼方法引數個數就是可變的了

  • 可變引數定義格式

    修飾符 返回值型別 方法名(資料型別… 變數名) {  }
    
  • 可變引數的注意事項

    • 這裡的變數其實是一個陣列
    • 如果一個方法有多個引數,包含可變引數,可變引數要放在最後
  • 可變引數的基本使用

    public class ArgsDemo01 {
        public static void main(String[] args) {
            System.out.println(sum(10, 20));
            System.out.println(sum(10, 20, 30));
            System.out.println(sum(10, 20, 30, 40));
    
            System.out.println(sum(10,20,30,40,50));
            System.out.println(sum(10,20,30,40,50,60));
            System.out.println(sum(10,20,30,40,50,60,70));
            System.out.println(sum(10,20,30,40,50,60,70,80,90,100));
        }
    
    //    public static int sum(int b,int... a) {
    //        return 0;
    //    }
    
        public static int sum(int... a) {
            int sum = 0;
            for(int i : a) {
                sum += i;
            }
            return sum;
        }
    }
    

2.2可變引數的使用

  • Arrays工具類中有一個靜態方法:

    • public static List asList(T… a):返回由指定陣列支援的固定大小的列表
    • 返回的集合不能做增刪操作,可以做修改操作
  • List介面中有一個靜態方法:

    • public static List of(E… elements):返回包含任意數量元素的不可變列表
    • 返回的集合不能做增刪改操作
  • Set介面中有一個靜態方法:

    • public static Set of(E… elements) :返回一個包含任意數量元素的不可變集合
    • 在給元素的時候,不能給重複的元素
    • 返回的集合不能做增刪操作,沒有修改的方法
  • 示例程式碼

    public class ArgsDemo02 {
        public static void main(String[] args) {
            //public static <T> List<T> asList(T... a):返回由指定陣列支援的固定大小的列表
    //        List<String> list = Arrays.asList("hello", "world", "java");
    //
            list.add("javaee"); //UnsupportedOperationException
            list.remove("world"); //UnsupportedOperationException
    //        list.set(1,"javaee");
    //
    //        System.out.println(list);
    
            //public static <E> List<E> of(E... elements):返回包含任意數量元素的不可變列表
    //        List<String> list = List.of("hello", "world", "java", "world");
    //
            list.add("javaee");//UnsupportedOperationException
            list.remove("java");//UnsupportedOperationException
            list.set(1,"javaee");//UnsupportedOperationException
    //
    //        System.out.println(list);
    
            //public static <E> Set<E> of(E... elements) :返回一個包含任意數量元素的不可變集合
    //        Set<String> set = Set.of("hello", "world", "java","world"); //IllegalArgumentException
            //Set<String> set = Set.of("hello", "world", "java");
    
    //        set.add("javaee");//UnsupportedOperationException
    //        set.remove("world");//UnsupportedOperationException
    
            //System.out.println(set);
        }
    }
    

相關文章