乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java泛型詳解

       sxw6wduc8b7bn5 2020-02-14
      2516326-5475e88a458a09e4.png

      一,打破砂鍋問到底

      泛型存在的意義?
      泛型類,泛型接口,泛型方法如何定義?
      如何限定類型變量?
      泛型中使用的約束和局限性有哪些?
      泛型類型的繼承規(guī)則是什么?
      泛型中的通配符類型是什么?
      如何獲取泛型的參數(shù)類型?
      虛擬機是如何實現(xiàn)泛型的?
      在日常開發(fā)中是如何運用泛型的?

      Java泛型詳解.png

      二,曉之以理動之以碼

      1,泛型的定義以及存在意義

      泛型,即“參數(shù)化類型”。就是將類型由原來的具體的類型參數(shù)化,類似于方法中的變量參數(shù),此時類型也定義成參數(shù)形式(可以稱之為類型形參),然后在使用/調(diào)用時傳入具體的類型(類型實參)。
      例如:GenericClass<T>{}

      一些常用的泛型類型變量:
      E:元素(Element),多用于java集合框架
      K:關(guān)鍵字(Key)
      N:數(shù)字(Number)
      T:類型(Type)
      V:值(Value)

      如果要實現(xiàn)不同類型的加法,每種類型都需要重載一個add方法

      package com.jay.java.泛型.needGeneric;
      
      /**
       * Author:Jay On 2019/5/9 16:06
       * <p>
       * Description: 為什么使用泛型
       */
      public class NeedGeneric1 {
      
          private static int add(int a, int b) {
              System.out.println(a + "+" + b + "=" + (a + b));
              return a + b;
          }
      
          private static float add(float a, float b) {
              System.out.println(a + "+" + b + "=" + (a + b));
              return a + b;
          }
      
          private static double add(double a, double b) {
              System.out.println(a + "+" + b + "=" + (a + b));
              return a + b;
          }
      
          private static <T extends Number> double add(T a, T b) {
              System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));
              return a.doubleValue() + b.doubleValue();
          }
      
          public static void main(String[] args) {
              NeedGeneric1.add(1, 2);
              NeedGeneric1.add(1f, 2f);
              NeedGeneric1.add(1d, 2d);
              NeedGeneric1.add(Integer.valueOf(1), Integer.valueOf(2));
              NeedGeneric1.add(Float.valueOf(1), Float.valueOf(2));
              NeedGeneric1.add(Double.valueOf(1), Double.valueOf(2));
          }
      }
      
      

      取出集合元素時需要人為的強制類型轉(zhuǎn)化到具體的目標(biāo)類型,且很容易現(xiàn)“java.lang. ClassCast Exception”異常。

      package com.jay.java.泛型.needGeneric;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * Author:Jay On 2019/5/9 16:23
       * <p>
       * Description: 為什么要使用泛型
       */
      public class NeedGeneric2 {
          static class C{
      
          }
          public static void main(String[] args) {
              List list=new ArrayList();
              list.add("A");
              list.add("B");
              list.add(new C());
              list.add(100);
              //1.當(dāng)我們將一個對象放入集合中,集合不會記住此對象的類型,當(dāng)再次從集合中取出此對象時,改對象的編譯類型變成了Object類型,但其運行時類型任然為其本身類型。
              //2.因此,//1處取出集合元素時需要人為的強制類型轉(zhuǎn)化到具體的目標(biāo)類型,且很容易出現(xiàn)“java.lang.ClassCastException”異常。
              for (int i = 0; i < list.size(); i++) {
      //            System.out.println(list.get(i));
                  String value= (String) list.get(i);
                  System.out.println(value);
              }
          }
      }
      
      

      所以使用泛型的意義在于
      1,適用于多種數(shù)據(jù)類型執(zhí)行相同的代碼(代碼復(fù)用)
      2, 泛型中的類型在使用時指定,不需要強制類型轉(zhuǎn)換(類型安全,編譯器會檢查類型)

      2,泛型類的使用

      定義一個泛型類:public class GenericClass<T>{}

      package com.jay.java.泛型.DefineGeneric;
      
      /**
       * Author:Jay On 2019/5/9 16:49
       * <p>
       * Description: 泛型類
       */
      public class GenericClass<T> {
          private T data;
      
          public T getData() {
              return data;
          }
      
          public void setData(T data) {
              this.data = data;
          }
      
          public static void main(String[] args) {
              GenericClass<String> genericClass=new GenericClass<>();
              genericClass.setData("Generic Class");
              System.out.println(genericClass.getData());
          }
      }
      

      3,泛型接口的使用

      定義一個泛型接口:public interface GenericIntercace<T>{}

      /**
       * Author:Jay On 2019/5/9 16:57
       * <p>
       * Description: 泛型接口
       */
      public interface GenericIntercace<T> {
           T getData();
      }
      

      實現(xiàn)泛型接口方式一:public class ImplGenericInterface1<T> implements GenericIntercace<T>

      /**
       * Author:Jay On 2019/5/9 16:59
       * <p>
       * Description: 泛型接口實現(xiàn)類-泛型類實現(xiàn)方式
       */
      public class ImplGenericInterface1<T> implements GenericIntercace<T> {
          private T data;
      
          private void setData(T data) {
              this.data = data;
          }
      
          @Override
          public T getData() {
              return data;
          }
      
          public static void main(String[] args) {
              ImplGenericInterface1<String> implGenericInterface1 = new ImplGenericInterface1<>();
              implGenericInterface1.setData("Generic Interface1");
              System.out.println(implGenericInterface1.getData());
          }
      }
      

      實現(xiàn)泛型接口方式二:public class ImplGenericInterface2 implements GenericIntercace<String> {}

      /**
       * Author:Jay On 2019/5/9 17:01
       * <p>
       * Description: 泛型接口實現(xiàn)類-指定具體類型實現(xiàn)方式
       */
      public class ImplGenericInterface2 implements GenericIntercace<String> {
          @Override
          public String getData() {
              return "Generic Interface2";
          }
      
          public static void main(String[] args) {
              ImplGenericInterface2 implGenericInterface2 = new ImplGenericInterface2();
              System.out.println(implGenericInterface2.getData());
          }
      }
      

      4,泛型方法的使用

      定義一個泛型方法: private static<T> TgenericAdd(T a, T b) {}

      /**
       * Author:Jay On 2019/5/10 10:46
       * <p>
       * Description: 泛型方法
       */
      public class GenericMethod1 {
          private static int add(int a, int b) {
              System.out.println(a + "+" + b + "=" + (a + b));
              return a + b;
          }
      
          private static <T> T genericAdd(T a, T b) {
              System.out.println(a + "+" + b + "="+a+b);
              return a;
          }
      
          public static void main(String[] args) {
              GenericMethod1.add(1, 2);
              GenericMethod1.<String>genericAdd("a", "b");
          }
      }
      
      /**
       * Author:Jay On 2019/5/10 16:22
       * <p>
       * Description: 泛型方法
       */
      public class GenericMethod3 {
      
          static class Animal {
              @Override
              public String toString() {
                  return "Animal";
              }
          }
      
          static class Dog extends Animal {
              @Override
              public String toString() {
                  return "Dog";
              }
          }
      
          static class Fruit {
              @Override
              public String toString() {
                  return "Fruit";
              }
          }
      
          static class GenericClass<T> {
      
              public void show01(T t) {
                  System.out.println(t.toString());
              }
      
              public <T> void show02(T t) {
                  System.out.println(t.toString());
              }
      
              public <K> void show03(K k) {
                  System.out.println(k.toString());
              }
          }
      
          public static void main(String[] args) {
              Animal animal = new Animal();
              Dog dog = new Dog();
              Fruit fruit = new Fruit();
              GenericClass<Animal> genericClass = new GenericClass<>();
              //泛型類在初始化時限制了參數(shù)類型
              genericClass.show01(dog);
      //        genericClass.show01(fruit);
      
              //泛型方法的參數(shù)類型在使用時指定
              genericClass.show02(dog);
              genericClass.show02(fruit);
      
              genericClass.<Animal>show03(animal);
              genericClass.<Animal>show03(dog);
              genericClass.show03(fruit);
      //        genericClass.<Dog>show03(animal);
          }
      }
      

      5,限定泛型類型變量

      1,對類的限定:public class TypeLimitForClass<T extends List & Serializable>{}
      2,對方法的限定:public static<T extends Comparable<T>>T getMin(T a, T b) {}

      /**
       * Author:Jay On 2019/5/10 16:38
       * <p>
       * Description: 類型變量的限定-方法
       */
      public class TypeLimitForMethod {
      
          /**
           * 計算最小值
           * 如果要實現(xiàn)這樣的功能就需要對泛型方法的類型做出限定
           */
      //    private static <T> T getMin(T a, T b) {
      //        return (a.compareTo(b) > 0) ? a : b;
      //    }
      
          /**
           * 限定類型使用extends關(guān)鍵字指定
           * 可以使類,接口,類放在前面接口放在后面用&符號分割
           * 例如:<T extends ArrayList & Comparable<T> & Serializable>
           */
          public static <T extends Comparable<T>> T getMin(T a, T b) {
              return (a.compareTo(b) < 0) ? a : b;
          }
      
          public static void main(String[] args) {
              System.out.println(TypeLimitForMethod.getMin(2, 4));
              System.out.println(TypeLimitForMethod.getMin("a", "r"));
          }
      }
      
      /**
       * Author:Jay On 2019/5/10 17:02
       * <p>
       * Description: 類型變量的限定-類
       */
      public class TypeLimitForClass<T extends List & Serializable> {
          private T data;
      
          public T getData() {
              return data;
          }
      
          public void setData(T data) {
              this.data = data;
          }
      
          public static void main(String[] args) {
              ArrayList<String> stringArrayList = new ArrayList<>();
              stringArrayList.add("A");
              stringArrayList.add("B");
              ArrayList<Integer> integerArrayList = new ArrayList<>();
              integerArrayList.add(1);
              integerArrayList.add(2);
              integerArrayList.add(3);
              TypeLimitForClass<ArrayList> typeLimitForClass01 = new TypeLimitForClass<>();
              typeLimitForClass01.setData(stringArrayList);
              TypeLimitForClass<ArrayList> typeLimitForClass02 = new TypeLimitForClass<>();
              typeLimitForClass02.setData(integerArrayList);
      
              System.out.println(getMinListSize(typeLimitForClass01.getData().size(), typeLimitForClass02.getData().size()));
      
          }
      
          public static <T extends Comparable<T>> T getMinListSize(T a, T b) {
              return (a.compareTo(b) < 0) ? a : b;
          }
      

      6,泛型中的約束和局限性

      1,不能實例化泛型類
      2,靜態(tài)變量或方法不能引用泛型類型變量,但是靜態(tài)泛型方法是可以的
      3,基本類型無法作為泛型類型
      4,無法使用instanceof關(guān)鍵字或==判斷泛型類的類型
      5,泛型類的原生類型與所傳遞的泛型無關(guān),無論傳遞什么類型,原生類是一樣的
      6,泛型數(shù)組可以聲明但無法實例化
      7,泛型類不能繼承Exception或者Throwable
      8,不能捕獲泛型類型限定的異常但可以將泛型限定的異常拋出

      /**
       * Author:Jay On 2019/5/10 17:41
       * <p>
       * Description: 泛型的約束和局限性
       */
      public class GenericRestrict1<T> {
          static class NormalClass {
      
          }
      
          private T data;
      
          /**
           * 不能實例化泛型類
           * Type parameter 'T' cannot be instantiated directly
           */
          public void setData() {
              //this.data = new T();
          }
      
          /**
           * 靜態(tài)變量或方法不能引用泛型類型變量
           * 'com.jay.java.泛型.restrict.GenericRestrict1.this' cannot be referenced from a static context
           */
      //    private static T result;
      
      //    private static T getResult() {
      //        return result;
      //    }
      
          /**
           * 靜態(tài)泛型方法是可以的
           */
          private static <K> K getKey(K k) {
              return k;
          }
      
          public static void main(String[] args) {
              NormalClass normalClassA = new NormalClass();
              NormalClass normalClassB = new NormalClass();
              /**
               * 基本類型無法作為泛型類型
               */
      //        GenericRestrict1<int> genericRestrictInt = new GenericRestrict1<>();
              GenericRestrict1<Integer> genericRestrictInteger = new GenericRestrict1<>();
              GenericRestrict1<String> genericRestrictString = new GenericRestrict1<>();
              /**
               * 無法使用instanceof關(guān)鍵字判斷泛型類的類型
               * Illegal generic type for instanceof
               */
      //        if(genericRestrictInteger instanceof GenericRestrict1<Integer>){
      //            return;
      //        }
      
              /**
               * 無法使用“==”判斷兩個泛型類的實例
               * Operator '==' cannot be applied to this two instance
               */
      //        if (genericRestrictInteger == genericRestrictString) {
      //            return;
      //        }
      
              /**
               * 泛型類的原生類型與所傳遞的泛型無關(guān),無論傳遞什么類型,原生類是一樣的
               */
              System.out.println(normalClassA == normalClassB);//false
              System.out.println(genericRestrictInteger == genericRestrictInteger);//
              System.out.println(genericRestrictInteger.getClass() == genericRestrictString.getClass()); //true
              System.out.println(genericRestrictInteger.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
              System.out.println(genericRestrictString.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
      
              /**
               * 泛型數(shù)組可以聲明但無法實例化
               * Generic array creation
               */
              GenericRestrict1<String>[] genericRestrict1s;
      //        genericRestrict1s = new GenericRestrict1<String>[10];
              genericRestrict1s = new GenericRestrict1[10];
              genericRestrict1s[0]=genericRestrictString;
          }
      
      }
      
      /**
       * Author:Jay On 2019/5/10 18:45
       * <p>
       * Description: 泛型和異常
       */
      public class GenericRestrict2 {
      
          private class MyException extends Exception {
          }
      
          /**
           * 泛型類不能繼承Exception或者Throwable
           * Generic class may not extend 'java.lang.Throwable'
           */
      //    private class MyGenericException<T> extends Exception {
      //    }
      //
      //    private class MyGenericThrowable<T> extends Throwable {
      //    }
      
          /**
           * 不能捕獲泛型類型限定的異常
           * Cannot catch type parameters
           */
          public <T extends Exception> void getException(T t) {
      //        try {
      //
      //        } catch (T e) {
      //
      //        }
          }
      
          /**
           *可以將泛型限定的異常拋出
           */
          public <T extends Throwable> void getException(T t) throws T {
              try {
      
              } catch (Exception e) {
                  throw t;
              }
          }
      }
      

      7,泛型類型繼承規(guī)則

      1,對于泛型參數(shù)是繼承關(guān)系的泛型類之間是沒有繼承關(guān)系的
      2,泛型類可以繼承其它泛型類,例如: public class ArrayList<E> extends AbstractList<E>
      3,泛型類的繼承關(guān)系在使用中同樣會受到泛型類型的影響

      /**
       * Author:Jay On 2019/5/10 19:13
       * <p>
       * Description: 泛型繼承規(guī)則測試類
       */
      public class GenericInherit<T> {
          private T data1;
          private T data2;
      
          public T getData1() {
              return data1;
          }
      
          public void setData1(T data1) {
              this.data1 = data1;
          }
      
          public T getData2() {
              return data2;
          }
      
          public void setData2(T data2) {
              this.data2 = data2;
          }
      
          public static <V> void setData2(GenericInherit<Father> data2) {
      
          }
      
          public static void main(String[] args) {
      //        Son 繼承自 Father
              Father father = new Father();
              Son son = new Son();
              GenericInherit<Father> fatherGenericInherit = new GenericInherit<>();
              GenericInherit<Son> sonGenericInherit = new GenericInherit<>();
              SubGenericInherit<Father> fatherSubGenericInherit = new SubGenericInherit<>();
              SubGenericInherit<Son> sonSubGenericInherit = new SubGenericInherit<>();
      
              /**
               * 對于傳遞的泛型類型是繼承關(guān)系的泛型類之間是沒有繼承關(guān)系的
               * GenericInherit<Father> 與GenericInherit<Son> 沒有繼承關(guān)系
               * Incompatible types.
               */
              father = new Son();
      //        fatherGenericInherit=new GenericInherit<Son>();
      
              /**
               * 泛型類可以繼承其它泛型類,例如: public class ArrayList<E> extends AbstractList<E>
               */
              fatherGenericInherit=new SubGenericInherit<Father>();
      
              /**
               *泛型類的繼承關(guān)系在使用中同樣會受到泛型類型的影響
               */
              setData2(fatherGenericInherit);
      //        setData2(sonGenericInherit);
              setData2(fatherSubGenericInherit);
      //        setData2(sonSubGenericInherit);
      
          }
      
          private static class SubGenericInherit<T> extends GenericInherit<T> {
      
          }
      

      8,通配符類型

      1,<? extends Parent> 指定了泛型類型的上屆
      2,<? super Child> 指定了泛型類型的下屆
      3, <?> 指定了沒有限制的泛型類型

      通配符測試類結(jié)構(gòu).png
      /**
       * Author:Jay On 2019/5/10 19:51
       * <p>
       * Description: 泛型通配符測試類
       */
      public class GenericByWildcard {
          private static void print(GenericClass<Fruit> fruitGenericClass) {
              System.out.println(fruitGenericClass.getData().getColor());
          }
      
          private static void use() {
              GenericClass<Fruit> fruitGenericClass = new GenericClass<>();
              print(fruitGenericClass);
              GenericClass<Orange> orangeGenericClass = new GenericClass<>();
              //類型不匹配,可以使用<? extends Parent> 來解決
      //        print(orangeGenericClass);
          }
      
          /**
           * <? extends Parent> 指定了泛型類型的上屆
           */
          private static void printExtends(GenericClass<? extends Fruit> genericClass) {
              System.out.println(genericClass.getData().getColor());
          }
      
          public static void useExtend() {
              GenericClass<Fruit> fruitGenericClass = new GenericClass<>();
              printExtends(fruitGenericClass);
              GenericClass<Orange> orangeGenericClass = new GenericClass<>();
              printExtends(orangeGenericClass);
      
              GenericClass<Food> foodGenericClass = new GenericClass<>();
              //Food是Fruit的父類,超過了泛型上屆范圍,類型不匹配
      //        printExtends(foodGenericClass);
      
              //表示GenericClass的類型參數(shù)的上屆是Fruit
              GenericClass<? extends Fruit> extendFruitGenericClass = new GenericClass<>();
              Apple apple = new Apple();
              Fruit fruit = new Fruit();
              /*
               * 道理很簡單,? extends X  表示類型的上界,類型參數(shù)是X的子類,那么可以肯定的說,
               * get方法返回的一定是個X(不管是X或者X的子類)編譯器是可以確定知道的。
               * 但是set方法只知道傳入的是個X,至于具體是X的那個子類,不知道。
               * 總結(jié):主要用于安全地訪問數(shù)據(jù),可以訪問X及其子類型,并且不能寫入非null的數(shù)據(jù)。
               */
      //        extendFruitGenericClass.setData(apple);
      //        extendFruitGenericClass.setData(fruit);
      
              fruit = extendFruitGenericClass.getData();
      
          }
      
          /**
           * <? super Child> 指定了泛型類型的下屆
           */
          public static void printSuper(GenericClass<? super Apple> genericClass) {
              System.out.println(genericClass.getData());
          }
      
          public static void useSuper() {
              GenericClass<Food> foodGenericClass = new GenericClass<>();
              printSuper(foodGenericClass);
      
              GenericClass<Fruit> fruitGenericClass = new GenericClass<>();
              printSuper(fruitGenericClass);
      
              GenericClass<Apple> appleGenericClass = new GenericClass<>();
              printSuper(appleGenericClass);
      
              GenericClass<HongFuShiApple> hongFuShiAppleGenericClass = new GenericClass<>();
              // HongFuShiApple 是Apple的子類,達不到泛型下屆,類型不匹配
      //        printSuper(hongFuShiAppleGenericClass);
      
              GenericClass<Orange> orangeGenericClass = new GenericClass<>();
              // Orange和Apple是兄弟關(guān)系,沒有繼承關(guān)系,類型不匹配
      //        printSuper(orangeGenericClass);
      
              //表示GenericClass的類型參數(shù)的下界是Apple
              GenericClass<? super Apple> supperAppleGenericClass = new GenericClass<>();
              supperAppleGenericClass.setData(new Apple());
              supperAppleGenericClass.setData(new HongFuShiApple());
              /*
               * ? super  X  表示類型的下界,類型參數(shù)是X的超類(包括X本身),
               * 那么可以肯定的說,get方法返回的一定是個X的超類,那么到底是哪個超類?不知道,
               * 但是可以肯定的說,Object一定是它的超類,所以get方法返回Object。
               * 編譯器是可以確定知道的。對于set方法來說,編譯器不知道它需要的確切類型,但是X和X的子類可以安全的轉(zhuǎn)型為X。
               * 總結(jié):主要用于安全地寫入數(shù)據(jù),可以寫入X及其子類型。
               */
      //        supperAppleGenericClass.setData(new Fruit());
      
              //get方法只會返回一個Object類型的值。
              Object data = supperAppleGenericClass.getData();
          }
      
          /**
           * <?> 指定了沒有限定的通配符
           */
          public static void printNonLimit(GenericClass<?> genericClass) {
              System.out.println(genericClass.getData());
          }
      
          public static void useNonLimit() {
              GenericClass<Food> foodGenericClass = new GenericClass<>();
              printNonLimit(foodGenericClass);
              GenericClass<Fruit> fruitGenericClass = new GenericClass<>();
              printNonLimit(fruitGenericClass);
              GenericClass<Apple> appleGenericClass = new GenericClass<>();
              printNonLimit(appleGenericClass);
      
              GenericClass<?> genericClass = new GenericClass<>();
              //setData 方法不能被調(diào)用, 甚至不能用 Object 調(diào)用;
      //        genericClass.setData(foodGenericClass);
      //        genericClass.setData(new Object());
              //返回值只能賦給 Object
              Object object = genericClass.getData();
      
          }
      
      }
      

      9,獲取泛型的參數(shù)類型

      Type是什么
      這里的Type指java.lang.reflect.Type, 是Java中所有類型的公共高級接口, 代表了Java中的所有類型. Type體系中類型的包括:數(shù)組類型(GenericArrayType)、參數(shù)化類型(ParameterizedType)、類型變量(TypeVariable)、通配符類型(WildcardType)、原始類型(Class)、基本類型(Class), 以上這些類型都實現(xiàn)Type接口.

      參數(shù)化類型,就是我們平常所用到的泛型List、Map;
      數(shù)組類型,并不是我們工作中所使用的數(shù)組String[] 、byte[],而是帶有泛型的數(shù)組,即T[] ;
      通配符類型, 指的是<?>, <? extends T>等等
      原始類型, 不僅僅包含我們平常所指的類,還包括枚舉、數(shù)組、注解等;
      基本類型, 也就是我們所說的java的基本類型,即int,float,double等

      public interface ParameterizedType extends Type {
          // 返回確切的泛型參數(shù), 如Map<String, Integer>返回[String, Integer]
          Type[] getActualTypeArguments();
          
          //返回當(dāng)前class或interface聲明的類型, 如List<?>返回List
          Type getRawType();
          
          //返回所屬類型. 如,當(dāng)前類型為O<T>.I<S>, 則返回O<T>. 頂級類型將返回null 
          Type getOwnerType();
      }
      
      /**
       * Author:Jay On 2019/5/11 22:41
       * <p>
       * Description: 獲取泛型類型測試類
       */
      public class GenericType<T> {
          private T data;
      
          public T getData() {
              return data;
          }
      
          public void setData(T data) {
              this.data = data;
          }
      
          public static void main(String[] args) {
              GenericType<String> genericType = new GenericType<String>() {};
              Type superclass = genericType.getClass().getGenericSuperclass();
              //getActualTypeArguments 返回確切的泛型參數(shù), 如Map<String, Integer>返回[String, Integer]
              Type type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; 
              System.out.println(type);//class java.lang.String
          }
      }
      

      10,虛擬機是如何實現(xiàn)泛型的

      Java泛型是Java1.5之后才引入的,為了向下兼容。Java采用了C++完全不同的實現(xiàn)思想。Java中的泛型更多的看起來像是編譯期用的
      Java中泛型在運行期是不可見的,會被擦除為它的上級類型。如果是沒有限定的泛型參數(shù)類型,就會被替換為Object.

      GenericClass<String> stringGenericClass=new GenericClass<>();
      GenericClass<Integer> integerGenericClass=new GenericClass<>();
      

      C++中GenericClass<String>和GenericClass<Integer>是兩個不同的類型
      Java進行了類型擦除之后統(tǒng)一改為GenericClass<Object>

      /**
       * Author:Jay On 2019/5/11 16:11
       * <p>
       * Description:泛型原理測試類
       */
      public class GenericTheory {
          public static void main(String[] args) {
              Map<String, String> map = new HashMap<>();
              map.put("Key", "Value");
              System.out.println(map.get("Key"));
              GenericClass<String, String> genericClass = new GenericClass<>();
              genericClass.put("Key", "Value");
              System.out.println(genericClass.get("Key"));
          }
      
          public static class GenericClass<K, V> {
              private K key;
              private V value;
      
              public void put(K key, V value) {
                  this.key = key;
                  this.value = value;
              }
      
              public V get(V key) {
                  return value;
              }
          }
      
          /**
           * 類型擦除后GenericClass2<Object>
           * @param <T>
           */
          private class GenericClass2<T> {
      
          }
      
          /**
           * 類型擦除后GenericClass3<ArrayList>
           * 當(dāng)使用到Serializable時會將相應(yīng)代碼強制轉(zhuǎn)換為Serializable
           * @param <T>
           */
          private class GenericClass3<T extends ArrayList & Serializable> {
      
          }
      }
      

      對應(yīng)的字節(jié)碼文件

       public static void main(String[] args) {
              Map<String, String> map = new HashMap();
              map.put("Key", "Value");
              System.out.println((String)map.get("Key"));
              GenericTheory.GenericClass<String, String> genericClass = new GenericTheory.GenericClass();
              genericClass.put("Key", "Value");
              System.out.println((String)genericClass.get("Key"));
          }
      

      三,學(xué)以致用

      1,泛型解析JSON數(shù)據(jù)封裝

      api返回的json數(shù)據(jù)

      {
          "code":200,
          "msg":"成功",
          "data":{
              "name":"Jay",
              "email":"10086"
          }
      }
      

      BaseResponse .java

      /**
       * Author:Jay On 2019/5/11 20:48
       * <p>
       * Description: 接口數(shù)據(jù)接收基類
       */
      public class BaseResponse {
      
          private int code;
          private String msg;
      
          public int getCode() {
              return code;
          }
      
          public void setCode(int code) {
              this.code = code;
          }
      
          public String getMsg() {
              return msg;
          }
      
          public void setMsg(String msg) {
              this.msg = msg;
          }
      }
      

      UserResponse.java

      /**
       * Author:Jay On 2019/5/11 20:49
       * <p>
       * Description: 用戶信息接口實體類
       */
      public class UserResponse<T> extends BaseResponse {
          private T data;
      
          public T getData() {
              return data;
          }
      
          public void setData(T data) {
              this.data = data;
          }
      }
      

      2,泛型+反射實現(xiàn)巧復(fù)用工具類

      /**
       * Author:Jay On 2019/5/11 21:05
       * <p>
       * Description: 泛型相關(guān)的工具類
       */
      public class GenericUtils {
      
          public static class Movie {
              private String name;
              private Date time;
      
              public String getName() {
                  return name;
              }
      
              public Date getTime() {
                  return time;
              }
      
              public Movie(String name, Date time) {
                  this.name = name;
                  this.time = time;
              }
      
              @Override
              public String toString() {
                  return "Movie{" + "name='" + name + '\'' + ", time=" + time + '}';
              }
          }
      
          public static void main(String[] args) {
              List<Movie> movieList = new ArrayList<>();
              for (int i = 0; i < 5; i++) {
                  movieList.add(new Movie("movie" + i, new Date()));
              }
              System.out.println("排序前:" + movieList.toString());
      
              GenericUtils.sortAnyList(movieList, "name", true);
              System.out.println("按name正序排:" + movieList.toString());
      
              GenericUtils.sortAnyList(movieList, "name", false);
              System.out.println("按name逆序排:" + movieList.toString());
          }
      
          /**
           * 對任意集合的排序方法
           * @param targetList 要排序的實體類List集合
           * @param sortField  排序字段
           * @param sortMode   true正序,false逆序
           */
          public static <T> void sortAnyList(List<T> targetList, final String sortField, final boolean sortMode) {
              if (targetList == null || targetList.size() < 2 || sortField == null || sortField.length() == 0) {
                  return;
              }
              Collections.sort(targetList, new Comparator<Object>() {
                  @Override
                  public int compare(Object obj1, Object obj2) {
                      int retVal = 0;
                      try {
                          // 獲取getXxx()方法名稱
                          String methodStr = "get" + sortField.substring(0, 1).toUpperCase() + sortField.substring(1);
                          Method method1 = ((T) obj1).getClass().getMethod(methodStr, null);
                          Method method2 = ((T) obj2).getClass().getMethod(methodStr, null);
                          if (sortMode) {
                              retVal = method1.invoke(((T) obj1), null).toString().compareTo(method2.invoke(((T) obj2), null).toString());
                          } else {
                              retVal = method2.invoke(((T) obj2), null).toString().compareTo(method1.invoke(((T) obj1), null).toString());
                          }
                      } catch (Exception e) {
                          System.out.println("List<" + ((T) obj1).getClass().getName() + ">排序異常!");
                          e.printStackTrace();
                      }
                      return retVal;
                  }
              });
          }
      }
      

      3,Gson庫中的泛型的使用-TypeToken

      /**
       * Author:Jay On 2019/5/11 22:11
       * <p>
       * Description: Gson庫中的泛型使用
       */
      public class GsonGeneric {
          public static class Person {
              private String name;
              private int age;
      
              public Person(String name, int age) {
                  this.name = name;
                  this.age = age;
              }
      
              @Override
              public String toString() {
                  return "Person{" +
                          "name='" + name + '\'' +
                          ", age=" + age +
                          '}';
              }
          }
      
          public static void main(String[] args) {
              Gson gson = new Gson();
              List<Person> personList = new ArrayList<>();
              for (int i = 0; i < 5; i++) {
                  personList.add(new Person("name" + i, 18 + i));
              }
              // Serialization
              String json = gson.toJson(personList);
              System.out.println(json);
              // Deserialization
              Type personType = new TypeToken<List<Person>>() {}.getType();
              List<Person> personList2 = gson.fromJson(json, personType);
              System.out.println(personList2);
          }
      }
      

      測試代碼

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多