课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 强制声明泛型的实际类型
  • 强制声明泛型的实际类型

    发布:昆明Java培训      来源:达内新闻      时间:2016-09-30

  • 昆明Java培训机构的老师知道,Arrays工具类有一个方法asList可以把一个变长参数或数组转变为列表,但是它有一个缺点:它所生成的list长度是不可变的,而这在我们的项目开发中有时会很不方便。如果你期望生成的列表长度可变 ,那就需要自己来写一个数组的工具类了,代码如下:

    1 class ArrayUtils {

    2    //把一个变长参数转化为列表,并且长度可变

    3    public static <T> List<T> asList(T... t) {

    4        List<T> list = new ArrayList<T>();

    5        Collections.addAll(list, t);

    6        return list;

    7    }

    8 }

    这很简单,与Arrays.asList的调用方式相同,我们传入一个泛型对象,然后返回相应的List,代码如下:

    public static void main(String[] args) {

    //正常用法

    List<String> list1 = ArrayUtils.asList("A", "B");

    //参数为空

    List list2 = ArrayUtils.asList();

    //参数为整型和浮点型的混合

    List list3 = ArrayUtils.asList(1, 2, 3.1);

    }

    这里有三个变量需要说明:

    (1)、变量list1:变量list1是一个常规用法,没有任何问题,泛型实际参数类型是String,返回结果就是一个容纳String元素的List对象。

    (2)、变量list2:变量list2它容纳的是什么元素呢?我们无法从代码中推断出list2列表到底容纳的是什么元素(因为它传递的参数是空,编译器也不知道泛型的实际参数类型是什么),不过,编译器会很聪明地推断出最顶层类Object就是 其泛型类型,也就是说list2的完整定义如下:

    List<Object> list2 = ArrayUtils.asList();

    如此一来,编译器就不会给出" unchecked "警告了。现在新的问题又出现了:如果期望list2是一个Integer类型的列表,而不是Object列表,因为后续的逻辑会把Integer类型加入到list2中,那该如何处理呢?

    强制类型转换(把asList强制转换成List<Integer>)?行不通,虽然Java泛型是编译期擦出的,但是List<Object>和List<Integer>没有继承关系,不能强制转换。

    重新声明一个List<Integer>,然后读取List<Object>元素,一个一个地向下转型过去?麻烦,而且效率又低。

    最好的解决办法是强制声明泛型类型,代码如下:

    List<Integer> intList = ArrayUtils.<Integer>asList();

    就这么简单,asList方法要求的是一个泛型参数,那我们就在输入前定义这是一个Integer类型的参数,当然,输出也是Integer类型的集合了。

    (3)、变量list3:变量list3有两种类型的元素:整数类型和浮点类型,那它生成的List泛型化参数应该是什么呢?是Integer和Float的父类Number?你太高看编译器了,它不会如此推断的,当它发现多个元素的实际类型不一致时就会直接确 认泛型类型是Object,而不会去追索元素的公共父类是什么,但是对于list3,我们更期望它的泛型参数是Number,都是数字嘛,参照list2变量,代码修改如下:

    List<Number> list3 = ArrayUtils.<Number>asList(1, 2, 3.1);

    Number是Integer和Float的父类,先把三个输入参数、输出参数同类型,问题是我们要在什么时候明确泛型类型呢?一句话:无法从代码中推断出泛型的情况下,即可强制声明泛型类型。

    了解详情请登陆昆明达内Java培训官网(km.Java.tedu.cn)!

    推荐文章

上一篇:不能初始化泛型参数和数组

下一篇:不同的场景使用不同的泛型通配符

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56