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代码]强制声明泛型的实际类型的更多相关文章

  1. [改善Java代码]不能初始化泛型参数和数组

    泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码: class Foo<T>{ //private T t =new T();//报错Cannot inst ...

  2. [改善Java代码]Java的泛型是类型擦除的

    泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型. Java泛型(Generi ...

  3. [改善Java代码]数组的真实类型必须是泛型类型的子类型

    List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变. toArray(T[] a)虽然返回的是T类型的数组, ...

  4. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  5. [改善Java代码]用枚举实现工厂方法模式更简洁

    工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到 ...

  6. Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题

    在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...

  7. [改善Java代码]警惕泛型是不能协变和逆变的

    什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是 ...

  8. [改善Java代码]不同的场景使用不同的泛型通配符

    Java泛型支持通配符(Wildcard),可以单独使用一个"?"表示任意类,也可以使用extends关键字标识某一类(接口)的子类型,还可以使用super关键字标识某一类(接口) ...

  9. [改善Java代码]静态变量一定要先声明后赋值

    建议32: 静态变量一定要先声明后赋值 这标题看着让人很纳闷,什么叫做变量一定要先声明后赋值?Java中的变量不都是先声明后使用的吗?难道还能先使用后声明?能不能暂且不说,我们先来看一个例子,代码如下 ...

随机推荐

  1. (转)UML序列图总结

    序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色用一条虚线 ...

  2. How to include cascading style sheets (CSS) in JSF

    In JSF 2.0, you can use <h:outputStylesheet /> output a css file. For example, <h:outputSty ...

  3. stdlib.h 头文件

    stdlib 头文件即standard library标准库头文件.stdlib.h里面定义了五种类型.一些宏和通用工具函数. 类型例如size_t.wchar_t.div_t.ldiv_t和lldi ...

  4. poj 1517 u Calculate e

    u Calculate e Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19465   Accepted: 11362   ...

  5. [iOS 多线程 & 网络 - 2.9] - ASI框架

    A.ASI基本知识 1.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大. ASI的实现基于底层的CFNetwork框架,因此运行效率很高. ASI的g ...

  6. [iOS 多线程 & 网络 - 2.1] - 解析json

    A.iOS中json的基本使用 1.解析json数据 (1)json反序列化 对象{}格式 {key : value, key : value,...} 的键值对的结构可以反序列化为OC中的NSDic ...

  7. EasyUI datetimebox设置默认值为当前时间

    设置value="${notices.release_time}" <input class="easyui-validatebox easyui-datetime ...

  8. [置顶] 《Windows编程零基础》__2 一个完整的程序

    Windows开发的常识 1)窗口 Windows中最基本的概念也许就是窗口了,每一个前台程序都至少有一个窗口,一个窗口也是你可以看到的部分,比如,QQ有如下的登录窗口 基本上你在Windows中可见 ...

  9. strutx.xml中配置文件的讲解

    Struts2框架的核心就是struts.xml文件了,该文件主要负责管理Struts的2的业务控制组件的核心内容.为了避免struts.xml的文件国 语庞大和臃肿,我们可以通过把一个struts. ...

  10. JAVA-开发环境搭建之JDK安装配置教程

    在进行java开发前先要搭建java的开发环境 下载java的开发环境eclipse 安装&配置环境变量 1,JDK安装