zoukankan      html  css  js  c++  java
  • 泛型类型限定和通配符类型限定

    泛型类型变量的限定

    泛型的基础知识可以参考其他教程。

    如果在方法前指定了<T>,那么就是说,方法的这个泛型类型和类定义时的泛型类型无关,这个特性让泛型方法可以定义在普通类中而不是泛型类中。

    我们都知道,泛型中可以限定类型变量必须实现某几个接口或者继承某个类,多个限定类型用&分隔,类必须放在限定列表中所有接口的前面。例如:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.io.Serializable;  
    2.   
    3. /** 
    4.  * ICE 
    5.  * 2016/10/17 0017 14:12 
    6.  */  
    7. public class Demo {  
    8.     public static void main(String[] args) {  
    9.         D<A> d = new D<>();  
    10.         A a = new A();  
    11.         d.test1(a);  
    12.         B b = new B();  
    13.         d.test1(b);  
    14.         C c = new C();  
    15.         d.test1(c);  
    16.   
    17.         d.test2("test");  
    18.     }  
    19. }  
    20.   
    21. class A implements Serializable, Cloneable {  
    22.     @Override  
    23.     public String toString() {  
    24.         return "A{}";  
    25.     }  
    26. }  
    27.   
    28. class B extends A {  
    29.     @Override  
    30.     public String toString() {  
    31.         return "B{}";  
    32.     }  
    33. }  
    34.   
    35. class C extends A {  
    36.     @Override  
    37.     public String toString() {  
    38.         return "C{}";  
    39.     }  
    40. }  
    41.   
    42. class D<T extends A & Serializable & Cloneable> {  
    43.     public void test1(T t) {  
    44.         System.out.println(t);  
    45.     }  
    46.   
    47.     public <T> void test2(T t) {  
    48.         System.out.println(t);  
    49.     }  
    50. }  

    输出:

    [plain] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. A{}  
    2. B{}  
    3. C{}  
    4. test  

    通配符类型

    通配符“?”同样可以对类型进行限定。可以分为子类型限定、超类型限定和无限定。通配符不是类型变量,因此不能在代码中使用"?"作为一种类型。

    子类型限定

    表示类型的上界,类似泛型的类型变量限定,格式是:? extends X。

    特点:

    1、限定为X和X的子类型,但不知道具体是哪个子类型,可能是怕导致类型转换错误(比如向下转型时编译不会报错,但是如果超类引用不是指向子类对象,那么运行时会报错),所以作为方法的参数时,这里禁止传递特定的类型。

    2、作为方法的参数时,可以传递null。

    作用:主要用来安全地访问数据,可以访问X及其子类型。

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. /** 
    5.  * ICE 
    6.  * 2016/10/17 0017 14:12 
    7.  */  
    8. public class Demo {  
    9.     public static void main(String[] args) {  
    10.         A a = new A();  
    11.         B b = new B();  
    12.         C c = new C();  
    13.   
    14.         List<A> list = new ArrayList<>();  
    15.         list.add(a);  
    16.         list.add(b);  
    17.         list.add(c);  
    18.         //根据list的值,我们可以给列表中的对象做<? extends A>限定,因为都是A和A的子类,get返回值赋给A是完全合法的  
    19.         List<? extends A> list1 = list;  
    20.         list.add(null);  
    21.         for (int i = 0; i < list1.size(); i++) {  
    22.             A a1 = list1.get(i);  
    23.             System.out.println(a1);  
    24.         }  
    25.   
    26.         //这里如果set任何非null的值,编译器都会报错  
    27.         D<? extends A> d = new D<>();  
    28.         d.set(null);  
    29.     }  
    30. }  
    31.   
    32. class A {  
    33.     @Override  
    34.     public String toString() {  
    35.         return "A{}";  
    36.     }  
    37. }  
    38.   
    39. class B extends A {  
    40.     @Override  
    41.     public String toString() {  
    42.         return "B{}";  
    43.     }  
    44. }  
    45.   
    46. class C extends A {  
    47.     @Override  
    48.     public String toString() {  
    49.         return "C{}";  
    50.     }  
    51. }  
    52.   
    53. class D<T> {  
    54.   
    55.     public void test1(T t) {  
    56.         System.out.println(t);  
    57.     }  
    58.   
    59.     public void set(T t) {  
    60.   
    61.     }  
    62. }  

    输出:

    [plain] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. A{}  
    2. B{}  
    3. C{}  
    4. null  

    超类型限定

    表示类型的下界,格式是:? super X。

    特点:

    1、限定为X和X的超类型,直至Object类,因为不知道具体是哪个超类型,因此方法返回的类型只能赋给Object。

    2、因为可以向上转型,所以作为方法的参数时,可以传递X以及X的子类型。

    3、作为方法的参数时,可以传递null。

    作用:主要用来安全地写入数据,可以写入X及其子类型。

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * ICE 
    3.  * 2016/10/17 0017 14:12 
    4.  */  
    5. public class Demo {  
    6.     public static void main(String[] args) {  
    7.         A a = new A();  
    8.         B b = new B();  
    9.         C c = new C();  
    10.   
    11.         D<? super A> d = new D<>();  
    12.         Object o = d.get();  
    13.   
    14.         d.set(a);  
    15.         d.set(b);  
    16.         d.set(c);  
    17.         d.set(null);  
    18.     }  
    19. }  
    20.   
    21. class A {  
    22.     @Override  
    23.     public String toString() {  
    24.         return "A{}";  
    25.     }  
    26. }  
    27.   
    28. class B extends A {  
    29.     @Override  
    30.     public String toString() {  
    31.         return "B{}";  
    32.     }  
    33. }  
    34.   
    35. class C extends A {  
    36.     @Override  
    37.     public String toString() {  
    38.         return "C{}";  
    39.     }  
    40. }  
    41.   
    42. class D<T> {  
    43.     public void set(T t) {  
    44.     }  
    45.   
    46.     public T get() {  
    47.         return null;  
    48.     }  
    49. }  

    无限定

    无限定不等于可以传任何值,相反,作为方法的参数时,只能传递null,作为方法的返回时,只能赋给Object。

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * ICE 
    3.  * 2016/10/17 0017 14:12 
    4.  */  
    5. public class Demo {  
    6.     public static void main(String[] args) {  
    7.         D<?> d = new D<>();  
    8.         Object o = d.get();  
    9.         d.set(null);  
    10.     }  
    11. }  
    12.   
    13. class A {  
    14.     @Override  
    15.     public String toString() {  
    16.         return "A{}";  
    17.     }  
    18. }  
    19.   
    20. class B extends A {  
    21.     @Override  
    22.     public String toString() {  
    23.         return "B{}";  
    24.     }  
    25. }  
    26.   
    27. class C extends A {  
    28.     @Override  
    29.     public String toString() {  
    30.         return "C{}";  
    31.     }  
    32. }  
    33.   
    34. class D<T> {  
    35.     public void set(T t) {  
    36.     }  
    37.   
    38.     public T get() {  
    39.         return null;  
    40.     }  
    41. }  

    有什么作用呢?对于一些简单的操作比如不需要实际类型的方法,就显得比泛型方法简洁。

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
      1. /** 
      2.  * ICE 
      3.  * 2016/10/17 0017 14:12 
      4.  */  
      5. public class Demo {  
      6.     public static void test(D<?> d) {  
      7.         System.out.println(d == null);  
      8.     }  
      9.   
      10.     public static <T> void test1(D<T> d) {  
      11.         System.out.println(d == null);  
      12.     }  
      13.   
      14.     public static void main(String[] args) {  
      15.         D d = new D();  
      16.         Demo.test(d);  
      17.         Demo.test1(d);  
      18.     }  
      19. }  
      20.   
      21. class D<T> {  
      22. }  
  • 相关阅读:
    流行的编程思维_面向对象-1
    db_Driver Manager
    SpringAOP
    Spring ioc的核心源码及拓展
    linux内核中把自己写的驱动添加到make menuconfig
    如何参考am335x ti官方技术
    AM335X linux嵌入式平台can驱动移植
    linux AM335x嵌入式平台spi驱动调试
    linux 设备树 gpio获取
    linux 为开发板添加板级文件config.h
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/6434696.html
Copyright © 2011-2022 走看看