泛型
泛型:java核心技术一书上说:泛型是需要的程序设计的手段.泛型程序设计是什么?就是说你写的代码可以被多个类使用.不需要在定义很多类.
泛型类:具有一个及多个类型变量的类.
类型变量:类的类型会发生变化,通常用T作为标识符.
虚拟机里面没有泛型类,只有普通类,擦除类型变量以后就变成了普通类了
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();
Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();
if(classStringArrayList.equals(classIntegerArrayList)){
Log.d("泛型测试","类型相同");
}
通过上面程序,运行结果为true证明程序是在编译结束后会擦除,就是说运行的时候不会有泛型机制
- 有擦除就有添上,但有个专业名词叫翻译泛型表达式,
比如Pair buddies=…,Employee buudy = buddies.getFirst(); - 当调用泛型方法的时候,如果擦除类型,编译器会自动添加进行强制类型转换.
泛型方法:泛型方法可以定义在普通类里面也可以定义在普通方法里面.
class ArrayAlg{
public static <T> T getMiddle(T... a){
return a[a.length/2]
}
public static void main(String []args){
//调用泛型方法
String middle = ArrayAlg. <String>getMiddle("john","Q","Public");
}
}
泛型为什么会出现
在泛型没有出现的时候,集合都是以Object[]类型,但是这样会出现两个问题:1.每次调用get方法的时候,都要进行强制转换,把Object类型强制转换为我们需要的类型,2.add()方法可以存任何类型的值在编译的时候不会报错.也就是你编写程序的时候不会报错,当你执行的时候会报错.
针对利用继承来实现通用程序设计所产生的问题,泛型提供了更好的解决方案:类型参数。例如,ArrayList类用一个类型参数来指出元素的类型。
ArrayList<String> stringValues=new ArrayList<String>();
这样具有很高的可读性,如果在这种情况下向stringValues.add(1) 编译器会自动帮我们检查,使得程序具有更好的安全性
总之,泛型的出现使得程序提高了安全性和可读性.
- 好了,出现了新的问题,不是说泛型在编译后会进行类型擦除吗,为什么stringValues不能添加Integer呢?
java编译器是通过先检查代码中泛型的类型,然后再进行类型擦除,再进行编译的。以如下代码为例
Pair<Integer> pair=new Pair<Integer> ();
pair.setValue(3);
Integer integer=pair.getValue();
System.out.println(integer);
擦除getValue()的返回类型后将返回Object类型,编译器自动插入Integer的强制类型转换。也就是说,编译器把这个方法调用翻译为两条字节码指令:1、对原始方法Pair.getValue的调用2、将返回的Object类型强制转换为Integer,此外存取一个泛型域的时候,编译器也会插入强转换命令.
如有错误,欢迎指正_