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. PLSQL存储过程校验身份证

    CREATE OR REPLACE FUNCTION FUN_CHECKIDCARD(PI_AAC002 VARCHAR2)   RETURN VARCHAR2 IS /*************** ...

  2. POJ 1847 Tram (最短路)

    Tram 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/N Description Tram network in Zagreb ...

  3. Spring 使用注解方式进行事物管理

    大家在使用spring的注解式事务管理时,对事务的传播行为和隔离级别可能有点不知所措,下边就详细的介绍下以备方便查阅. 事物注解方式: @Transactional 当标于类前时, 标示类中所有方法都 ...

  4. Umbraco中的Member登录时的Lock out功能

    请参看文章 https://our.umbraco.org/forum/using-umbraco-and-getting-started/76389-preventing-member-lock-o ...

  5. Spring REST实践之HATEOAS

    HATEOAS HATEOAS(The Hypermedia As The Engine Of Application Statue)是REST架构的主要约束."hepermedia&quo ...

  6. Thinkphp框架----微信公众测试号开发(2)

    ---恢复内容开始--- 最近忙着投简历找工作.现在继续更 微信回复图文设置. 效果: 页面HTML需要一个form表单 简单效果: 接下来是数据库 字段:id title(标题) text(描述) ...

  7. [C#] Control.Invoke方法和跨线程访问控件

    在设计界面时,我们经常需要将一些需要时间才能完成的操作放在另一个线程(不同于UI主线程)中执行.但是这些操作可能需要将其结果或完成情况通知主线程,比如调用窗体的方法,或者触发事件(由界面响应事件),很 ...

  8. Oracle DataGuard搭建(一)

    第一次搭建oracle dataguard.学oracle很长时间,却没有完整的搭过dg,说起来让人笑.总得有第一次,而且第一次总是很痛苦的. 数据库版本: Oracle Database 11g E ...

  9. 分析代码的利器 - ctags

    比方我们在分析代码的时候,须要看某一个方法或类的定义,我们须要临时跳转过去看一下,然后还能非常方便的回来.这时候ctags就派上用场了. 比方你有一个src目录,先用ctags对其生成索引: ctag ...

  10. Win7 不能安装 msi 解决办法

    Win7 不能安装Setup.msi解决办法 解决方案如下: 新建一个文本文件,输入msiexec /i d:\Setup.msi (假设文件名为Setup.msi ,放在d盘根目录下,即是安装程序的 ...