- 什么是泛型
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
eg:
package com.sun11;
//simple container example(produces complier warnings)
/**
*
* 刚才声明容器时没有预先定义类型,默认为Object,因为ArrayList保存的是Object,
* 所以可以将Apple对象和Orange对象放进容器中,当在使用ArrayList的get()方法来取出Apple对象时,得到的只是Object的引用,必须将其转型为Apple,因此,需在调用Apple的id()方法之前,强制进行转型,否则,
就会得到编译错误。
*/
import java.util.*;
class Apple{
private static long counter;
private final long id = counter++;
public long id(){return id;}
}
class Orange{
}
public class AppleAndOrangesWithoutGenerics {
@SuppressWarnings("unchecked")
public static void main(String[] args){
//定义一个ArrayList容器,不定义其类型
ArrayList apples = new ArrayList();
for (int i = 0; i < 3; i++)
apples.add(new Apple());
//not prevented from adding an orange to apples
apples.add(new Orange());
//此时apples容器存在4个对象,前3个是Apple类型,后一个是Orange类型
for (int i = 0; i <apples.size(); i++)
//get方法取值时得到的只是Object的引用,所以将其强制转化为Apple类型,否则编译错误
//当试图将Orange转化为Apple类型时,发生类型转换异常----
// java.lang.ClassCastException: com.sun11.Orange cannot be cast to com.sun11.Apple
System.out.println(((Apple)apples.get(i)).id());
//orange is detected only at run time
}
}
2:解决办法
eg:
package com.sun11;
import java.util.ArrayList;
public class AppleAndOrangesWithGenerics {
public static void main(String[] args){
ArrayList<Apple> apples = new ArrayList<Apple>();
for (int i = 0; i < 3; i++)
apples.add(new Apple());
//现在编译器可以阻止你将Orange放入到apples中,因为它是compile-time error
//apples.add(new Orange());
for (int i = 0; i < apples.size(); i++)
//将以安肃取出来,类型转换不再需要,因为apples知道保存的是什么类型
System.out.println(apples.get(i).id());
//using foreach来选中每个元素:
for(Apple c : apples)
System.out.println(c.id());
}
}
//输出
/**
*0
*1
*2
*0
*1
*2
**/
3:当你指定某个类型作为泛型参数时,你并不只限于将该确切类型的对象放入到容器中,向上转型也可以像作用于其他类型一样作用于泛型:
eg:
package com.sun11;
import java.util.*;
class GrannySmith extends Apple{}
class Gala extends Apple{}
class Braebun extends Apple{}
public class GenericsAndUpcasting {
public static void main(String[] args){
ArrayList<Apple> apples = new ArrayList<Apple>();
apples.add(new GrannySmith());
apples.add(new Gala());
apples.add(new Braebun());
for (Apple c : apples)
System.out.println(c);
}
}
//output
//com.sun11.GrannySmith@49e6f7cb
//com.sun11.Gala@5a965654
//com.sun11.Braebun@43fdd342
/**
* 可以将Apple的子类型添加到被指定为保存Apple对象的容器中
* 程序的输出是从Object默认的toString()方法产生的,该方法将打印类名
* 后面跟随该对象的散列码的无符号十六进制表示
*/