昆明java培训
达内昆明广州春城路

18487146383

热门课程

强制声明泛型的实际类型

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

昆明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)!

上一篇:不能初始化泛型参数和数组
下一篇:不同的场景使用不同的泛型通配符

腾讯游戏Switch独立销量领先——昆明达内

达内java语言编程学以致用

苹果技术:A11芯片上新菜【达内培训】

达内培训之国产手机vivo领跑,小米再上榜

选择城市和中心
贵州省

广西省

海南省