泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastException的可能。个人认为泛型就是你在存入的时候指定类型.在取出的时候不用进行类型转换.存什么取什么.
[url]http://www.ibm.com/developerworks/cn/java/j-lo-gj/[/url]
泛型详解
没有泛型之前
程序会抛出一个类型转换的异常
编译器不会提醒你程序有问题.但其实程序运行的时候会出错
有泛型之后
如果foo1的set方法set的是一个string的话.就会出现编译时错误.减少了类型转换异常的发生
泛型的其他特点
[url]http://www.ibm.com/developerworks/cn/java/j-lo-gj/[/url]
泛型详解
没有泛型之前
package com.smallq.jdk5;
public class ObjectFoo {
private Object foo;
public Object getFoo() {
return foo;
}
public void setFoo(Object foo) {
this.foo = foo;
}
public static void main(String[] args) {
ObjectFoo foo1 = new ObjectFoo();
foo1.setFoo(new Boolean(true));
String b=(String)foo1.getFoo();
System.out.println(b);
}
}
程序会抛出一个类型转换的异常
Exception in thread "main" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
at com.smallq.jdk5.ObjectFoo.main(ObjectFoo.java:18)
编译器不会提醒你程序有问题.但其实程序运行的时候会出错
有泛型之后
package com.smallq.jdk5;
public class GenericFoo<T> {
private T foo;
public T getFoo() {
return foo;
}
public void setFoo(T foo) {
this.foo = foo;
}
public static void main(String[] args) {
GenericFoo<Boolean> foo1 = new GenericFoo<Boolean>();
foo1.setFoo(new Boolean(true));
Boolean b = foo1.getFoo();
System.out.println(b);
}
}
如果foo1的set方法set的是一个string的话.就会出现编译时错误.减少了类型转换异常的发生
泛型的其他特点
package com.smallq.jdk5;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class GenericTest<T> {
private T foo;
public T getFoo() {
return foo;
}
public void setFoo(T foo) {
this.foo = foo;
}
/**
* @param args
*/
public static void main(String[] args) {
// 简单的说,实例化类型持有者时,它必須是实现List的类别或其子类别
// 要定义这样一个名称,您可以使用 ‘?’通配字元
// 并使用“extends”关键字限定类型持有者的型态
GenericTest<? extends List> foo1 = null;
foo1 = new GenericTest<ArrayList>();
foo1 = new GenericTest<LinkedList>();
// 实现类必须是指定类的父类
GenericTest<? super ArrayList> foo2 = null;
foo2 = new GenericTest<List>();
GenericTest<String> foo3 = new GenericTest<String>();
foo3.setFoo("hello world");
GenericTest<?> foo4 = null;
foo4 = foo3;
System.out.println(foo4.getFoo());
foo4.setFoo(null);
// 使用<?>或是<? extends SomeClass>的声明方式
// 意味著您只能通过该名称來取得所参考实例的信息,或者是移除某些信息,但
// 不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是
// 什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么
// 您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,
// 这就失去了使用泛型的意义。
// 所以下面这句不可以
// foo4.setFoo("abc");
System.out.println(foo4.getFoo());
}
}
package com.smallq.jdk5;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 通过extends关键字指定T的类型必须是list的子类或者实现类
* @author smallq
*
* @param <T>
*/
public class ListGenericFoo<T extends List> {
private T[] fooArray;
public T[] getFooArray() {
return fooArray;
}
public void setFooArray(T[] fooArray) {
this.fooArray = fooArray;
}
/**
* @param args
*/
public static void main(String[] args) {
ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();
LinkedList[] linkedList = new LinkedList[10];
ArrayList[] arrayList = new ArrayList[10];
foo1.setFooArray(linkedList);
foo2.setFooArray(arrayList);
ListGenericFoo<? extends List> foo3=null;
foo3=new ListGenericFoo<ArrayList>();
foo3=new ListGenericFoo<LinkedList>();
//下面这句就不可以.因为他没有实现List接口
//ListGenericFoo<HashMap> f=new ListGenericFoo<HashMap>();
}
}