Java泛型学习-20170819

来源:互联网 发布:阿里云邮件服务器设置 编辑:程序博客网 时间:2024/06/03 04:30

Java泛型学习系列文章:

Java泛型学习-20170816
http://blog.csdn.net/clandellen/article/details/77219824

Java泛型学习-20170817
http://blog.csdn.net/clandellen/article/details/77285616

Java泛型学习-20170818
http://blog.csdn.net/clandellen/article/details/77351555

前篇文章我们学习Java泛型最重要的知识,泛型的擦除与翻译,Java泛型基本运行机制你已经了解的很明白了。本篇文章将会为你带来泛型和Class,转型和instanceof,通配符的高级用法。

1.泛型和Class

上一篇文章,我们学习了泛型的擦除与翻译,有个问题需要探讨一下,看看下面的代码会输出什么?

    ArrayList<String> arrayList1 = new ArrayList<String>();    ArrayList<Integer> arrayList2 = new ArrayList<Integer>();    System.out.println(arrayList1.getClass().equals(arrayList2.getClass()));//运行结果这里输出:true

上述代码输出结果为true,getClass()方法就是获取当前实力对象对应的字节码Class对象,结果表明arrayList1和arrayList2对应的字节码Class对象是一样的,这说明泛型类只有一个Class,尽管泛型变量的参数不一样,可它们依旧有同一个Class生成的实例对象,拿ArrayList来说,不管你给泛型变量E传递了什么参数,不管是String还是Integer等,这些生成的ArrayList的实例对象都只对应同一个Class,那就是java.util.ArrayList。

2.转型和instanceof

泛型也可以进行转型,只不过如果代码写的不够谨慎,那么极容易出现ClassCastException异常,这是类型转换异常,比如如下代码就极有可能出现这种异常:

 public  static <T> T getT(T t){    String s = (String)t;//这里极有可能出现ClassCastException,前提是T的参数值不为String    System.out.println(s);    return t;}

那么如何把代码写的谨慎一些以避免ClassCastException的产生呢?使用instanceof就可以有效避免ClassCastException异常的产生。

关于instanceof:
对象运算符(instanceof)
对象运算符用来判断对象是否为某一类型,运算结果为boolean型。用法为:
对象标识符 instanceof 类型标识符
例如:
java.util.Date date = new java.util.Date();
System.out.println(date instanceof java.util.Date); // 结果为true
System.out.println(date instanceof java.sql.Date); // 结果为false

因此,我们可以上面的代码改写成如下所示,这才是正确的代码:

public  static <T> T getT(T t){    if(t instanceof String) {        String s = (String) t;        System.out.println("T是String类型的处理逻辑");    }else{        System.out.println("T不是String类型的处理逻辑");    }    System.out.println(s);    return t;}

3.通配符的高级用法

通配符我们在前面的文章中学到了,”ArrayList< ? extends Person >”,这是常规的通配符的使用,”ArrayList< ? extends Person >”表示对泛型类ArrayList< E >类中的泛型变量E进行匹配,将泛型变量E的通用类型匹配为Person或者Penson的子类的意思。既然可以指定一个具体的匹配类型,那么是不是可以指定一个不具体的匹配类型,我的意思是把Person换成泛型可以吗?这当然是可以的,这就是通配符号的高级用法,”ArrayList< ? extends T >”的意思是将泛型变量E的通用类型匹配为泛型变量T或者泛型变量T的子类,当然这个泛型变量T在你使用这个类的时候已经指定了,代码示例如下:

public class MyClass<T>{    public void  method(ArrayList<? extends T> arrayList){        for(T t:arrayList){            System.out.println(t);        }    }    public static void main(String[] args){        MyClass<String> myClass = new MyClass<String>();//这里已经指定T的值为String        ArrayList<Integer> integerList = new ArrayList<Integer>();         ArrayList<String>  stringList = new ArrayList<String>();        myClass.method(integerList);//报错        myClass.method(stringList);//不报错   }}