首页 > 代码库 > Java泛型

Java泛型

摘自:HERE

 

理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作:

List <Apple> box = ...;   Apple apple = box.get(0);  

上面的代码自身已表达的很清楚:box是一个装有Apple对象的List。get方法返回一个Apple对象实例,这个过程不需要进行类型转换。没有泛型,上面的代码需要写成这样:

List box = ...;   Apple apple = (Apple) box.get(0);

很明显,泛型的主要好处就是让编译器保留参数的类型信息,执行类型检查,执行类型转换操作:编译器保证了这些类型转换的绝对无误。

泛型包含一个或多个类型参数

类型参数不能使基本类型

 

泛型的构成:

泛型类声明

泛型接口声明

泛型方法声明

泛型构造器(constructor)声明

 

泛型类和接口:如果一个类或接口上有一个或多个类型变量,那它就是泛型。类型变量由尖括号界定,放在类或接口名的后面:

public interface List<T> extends Collection<T> {   	...    }   

泛型方法和构造器(Constructor):

public static <t> T getFirst(List<T> list)

这个方法将会接受一个List<T>类型的参数,返回一个T类型的对象。

例子

你既可以使用Java类库里提供的泛型类,也可以使用自己的泛型类。

类型安全的写入数据…

下面的这段代码是个例子,我们创建了一个List<String>实例,然后装入一些数据:

List<String> str = new ArrayList<String>();str.add("Hello ");str.add("World.");

如果我们试图在List<String>装入另外一种对象,编译器就会提示错误:

str.add(1); //不能编译   

类型安全的读取数据…

当我们在使用List<String>对象时,它总能保证我们得到的是一个String对象:

String myString = str.get(0);   

遍历

类库中的很多类,诸如Iterator<T>,功能都有所增强,被泛型化。List<T>接口里的 iterator()方法现在返回的是Iterator<T>,由它的T next()方法返回的对象不需要再进行类型转换,你直接得到正确的类型。

for (Iterator<String> iter = str.iterator(); iter.hasNext();) {String s = iter.next();System.out.print(s);}

  

向上造型一个泛型对象的引用(Covariance,协变)

例如,假设我们有很多箱子,每个箱子里都装有不同的水果,我们需要找到一种方法能够通用的处理任何一箱水果。更通俗的说法,A是B的子类型,我们需要找到一种方法能够将C<A>类型的实例赋给一个C<B>类型的声明。

为了完成这种操作,我们需要使用带有通配符的扩展声明,就像下面的例子里那样:

List<Apple> apples = new ArrayList<Apple>();List<? extends Fruit> fruits = apples;

“? extends”是泛型类型的子类型相关性成为现实:Apple是Fruit的子类型,List<Apple> 是 List<? extends Fruit> 的子类型。 

 

向下造型一个泛型对象的引用(Contravariance,逆变)

现在我来介绍另外一种通配符:? super。如果类型B是类型A的超类型(父类型),那么C<B> 是 C<? super A> 的子类型:

List<Fruit> fruits = new ArrayList<Fruit>();List<? super Apple> = fruits;

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-------------------------------------------------------------

摘录自这里,本篇文章只是简单地记录一些自己从中看到的东西。

 

泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

该代码不使用泛型

List li = new ArrayList();li.add(new Integer(3));Integer i = (Integer) li.get(0);

该代码使用泛型

List<Integer> li = new ArrayList<Integer>();li.add(new Integer(3));Integer i = li.get(0);

在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。