[改善Java代码]强制声明泛型的实际类型
Arrays工具类有一个方法asList可以把一个变长参数或数组变成列表,但是它有一个缺点:它所生成的List长度是不可改变的,而这在我们的项目开发中很不方便.
import java.util.Arrays;
import java.util.List; public class Client {
public static void main(String[] args) {
String[] strArray = {"1","18","71","61","51"};
List<String> asList = Arrays.asList(strArray);
//asList.add("tttt");//会在这一行报错:Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println(asList);
}
}
如果你期望生成的列表长度是可变的,那就需要自己来写一个数组的工具类了.代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class Client { 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);
} } class ArrayUtils{
//把一个变长参数转变为列表
public static <T> List<T> asList(T...t){
List<T> list = new ArrayList<T>();
Collections.addAll(list, t);
return list;
}
}
与Arrays.asList的调用方式相同,我们传入一个泛型对象,然后返回相应的List.
这里有三个变量需要说明:
(1)变量list1
泛型实际的参数类型是String,返回的结果也就是容纳String元素的List对象.
(2)变量list2
传递的是空参数,编译器也不知道泛型的实际参数类型是什么,不过编译器会认为Object就是其泛型类型,也就是说list2的完整定义如下:
List<Object> list2 = ArrayUtils.asList();
这样编译时就不会给出"unchecked"警告了.
如果期望list2是一个Integer类型的列表,而不是Object列表,因为后续的逻辑会把Interger类型加入到list2中,如何处理?
强制类型转化,把asList强制转换成List<Integer>?行不通,虽然Java的泛型是编译擦除式的,但是List<Object>和List<Intger>没有继承关系,不能进行强制转换.
最好的解决办法是强制声明泛型类型,代码如下:
List<Integer> list22 = ArrayUtils.<Integer>asList();
asList方法要求的是一个泛型参数,那我们就在输入前定义这是一个Integer类型的参数,当然,输出也是Integer类型的集合了.
(3)变量list3
变量list3有两种类型的元素:整数类型和浮点类型,那它生成的List泛型化参数应该是什么呢?
Integer和Float的父类Number?你太高看编译器了,它不会如此的推断的,当它发现多个元素的实际类型不一致的时候就会直接确认泛型类型是Object.而不会去追查元素类的公共父类是什么,但是对于list3,我们更期望它的泛型参数是Number.参照list2变量,代码修改如下:
List<Number> list33 = ArrayUtils.<Number>asList(1,2,3.1);
Number是Integer和Float的父类,先把三个输入参数向上转型为Number,那么返回的结果也就是List<Number>类型了.
什么时候明确泛型类型呢?
一句话:无法从代码中推断出泛型类型的情况下,即可强制声明泛型类型.
[改善Java代码]强制声明泛型的实际类型的更多相关文章
- [改善Java代码]不能初始化泛型参数和数组
泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码: class Foo<T>{ //private T t =new T();//报错Cannot inst ...
- [改善Java代码]Java的泛型是类型擦除的
泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型. Java泛型(Generi ...
- [改善Java代码]数组的真实类型必须是泛型类型的子类型
List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变. toArray(T[] a)虽然返回的是T类型的数组, ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]用枚举实现工厂方法模式更简洁
工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到 ...
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...
- [改善Java代码]警惕泛型是不能协变和逆变的
什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是 ...
- [改善Java代码]不同的场景使用不同的泛型通配符
Java泛型支持通配符(Wildcard),可以单独使用一个"?"表示任意类,也可以使用extends关键字标识某一类(接口)的子类型,还可以使用super关键字标识某一类(接口) ...
- [改善Java代码]静态变量一定要先声明后赋值
建议32: 静态变量一定要先声明后赋值 这标题看着让人很纳闷,什么叫做变量一定要先声明后赋值?Java中的变量不都是先声明后使用的吗?难道还能先使用后声明?能不能暂且不说,我们先来看一个例子,代码如下 ...
随机推荐
- CodeForces 689E Mike and Geometry Problem (离散化+组合数)
Mike and Geometry Problem 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/I Description M ...
- thymeleaf的属性优先级
所有Thymeleaf属性定义一个数字优先,建立他们的顺序执行的标签.这个顺序是: Order Feature Attributes 1 Fragment inclusion th:includeth ...
- Cannot retrieve metalink for repository: epel. Please verify its path and try again
今天在测试环境使用yum安装,遇到一个问题: Error: Cannot retrieve metalink for repository: epel. Please verify its path ...
- 【Java】IO流简单分辨
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827509.html Java的IO流体系十分庞大,并且体系层次稍复杂,很容易记混或记错.在此,我把平时经常用 ...
- CoordinatorLayout的简单应用(材料设计新控件)
CoordinatorLayout字面意思为:协调布局,一般作为根布局使用.关于这个布局,记录一下两个用法,备忘. 一.配合 FloatingActionBar 使用 <?xml version ...
- ListCtrl控件的使用
list contrl控件的使用 .建立基于对话框的应用程序,布置界面,设置属性. 注意添加的是listctrl控件,不是listbox控件,在控件工具箱的倒数第五行list control控件. 属 ...
- 【转】移动端App测试实用指南
转自:互联网那点事 英文原文: http://mobile.smashingmagazine.com/2012/10/22/a-guide-to-mobile-app-testing/ 测试人员常被看 ...
- 配置集群Nginx+Memcached+Tomcat集群配置
上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家一起学习一下配置集群 1. Nginx Nginx是通过将多个Web Server绑定到同一个IP地址下,以实现多个WebS ...
- SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治
Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...
- HDU 4813 Hard Code 水题
Hard Code Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.act ...