Java基础:泛型及其擦除性、不可协变性
作者:网络转载 发布时间:[ 2015/7/3 11:49:47 ] 推荐标签:软件开发 编程语言
1.泛型语法:
泛型类: class ClassName<T>{}
泛型方法:public <T> void f(T x){}
基本指导原则:如果使用泛型方法可以取代将整个类泛型化,那么应该使用泛型方法,因为它可以让事情更加清楚。
2.为什么使用泛型?
在Java SE1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是:
(1)在编译时检查类型安全;
(2)并且所有的强制转换都是自动和隐式的,提高代码的重用率。
促成泛型出现引人注目的一个原因是为了创造容器类。
优先考虑泛型!!!
使用泛型比使用需要在客户端代码中进行转换的类型来的更加安全,也更加容易。
在设计新类型的时候,要确保它们不需要这种转换可以使用。这通常意味着要把类做成是泛型的。
比如
客户端代码使用Stack的时候,如果不使用泛型,在取用Stack中的对象时还需要进行不安全的类型判断,类型转换等,而且代码还比较复杂。如果使用带泛型的Stack,客户端代码中不需要进行类型转换了,直接使用而且不会复杂。
3.泛型数组:
无法创建泛型数组,一般的解决方式是在任何想要使用泛型数组的地方使用ArrayList。
public <T> voidtest()
{
//Cannotcreate a generic array of T
T[]tList = new T[10];
int[]iList = new int[10];
//useArrayList<T>
ArrayList<T>sList = new ArrayList<T>();
}
4.类型擦除:
一、概念
类型擦除:将泛型类型中类型参数信息去除,只映射为一份字节码,在必要时进行类型检查和类型转换。
编译时通过两个步骤来对泛型类型的类型进行擦除:
1.将所有的泛型参数用其左边界(的父类型)类型替换。
2.移除所有的类型参数。
备注:擦除也是为什么泛型必须编译时进行类型检查的原因,因为运行时类型信息被擦除了。
二、擦除举例
(1)容器泛型类型擦除:
ArrayList<Integer>l1 = new ArrayList<Integer>();
ArrayList<String> l2= new ArrayList<String>();
LinkedList<Integer>l3 = new LinkedList<Integer>();
List<String> l4 =new LinkedList<String>();
System.out.println(l1.getClass().getName());
System.out.println(l2.getClass().getName());
System.out.println(l3.getClass().getName());
System.out.println(l4.getClass().getName());
//output
java.util.ArrayList
java.util.ArrayList
java.util.LinkedList
java.util.LinkedList
可以看到上面四个泛型类型的类型信息均被擦出掉了,比如ArrayList<Integer>和ArrayList<String>编译后生成的字节码是一份。
(2)自定义泛型类型擦除:
再看一个自定义的泛型类:
class TObject<T>
{
privateT obj;
publicvoid Set(T object)
{
this.obj= object;
System.out.println("T:"+object.getClass().getName());
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11