题外话:前几天我的笔记本电脑硬盘坏了,本子送到售后进行维修,需要2到3个工作日才能搞定。。现在木有本本用了,无奈就借了女朋友的本子先用着了。。现装的JDK,UltraEdit。。所以下面的图片中编译器的报错信息就变成了中文。。哎,脆弱的硬盘啊。。。
Java在J2SE 5.0后开始增加了泛型(Generics)功能,并且许多API都根据这个新的功能被重新改写了,例如List、Map、Set等与数据结构相关的类。如果我们不想使用泛型功能,也可以用J2SE 1.4或以前的版本的语法来使用这些类,但编译的时候就会出现一些警告。如果对泛型了解不足,那么就会完全不知编译器所云。因此,了解或学会使用泛型是十分必要的。
1、在没有泛型之前
先来看2个类:
IntegetTest :
class IntegerTest
{
private Integer integer;
public void setObj(Integer integer)
{
this.integer = integer;
}
public Integer getObj()
{
return integer;
}
}
BooleanTest :
class BooleanTest
{
private Boolean bool;
public void setObj(Boolean bool)
{
this.bool = bool;
}
public Boolean getObj()
{
return bool;
}
}
通过观察我们发现,这两个类除了Boolean和Integer这两个关键字不同外,其它的代码都相同。如此相似的类如果我们必须要写两份代码就难免有些冗杂。我们都知道,Object类是所有类的父类,因此用Object类来实现泛型或许是个不错的解决方案。如:
class ObjectTest
{
private Object obj;
public void setObj(Object obj)
{
this.obj = obj;
}
public Object getObj()
{
return obj;
}
}
于是我们在使用ObjectTest这个类时就需要编写如下代码:
ObjectTest obj = new ObjectTest();
obj.setObj(new Integer(100)); //传递一个Integer对象的引用
//由于getObj()方法返回的是一个Object类型对象的引用,因此需要强制转换为Integer
Integer I = (Integer)obj.getObj();
可以看出,如果要使用getObj()方法得到我们想要的对象,那么就必须
进行一次强制类型转换才能满足我们的需求。但问题就出在这里。很多时候,我们往往会忘记进行强制转换,这时候编译器就会报错:
因此这就需要开发人员在写代码的时候要额外注意。在没有泛型之前,所有存入List, Map, Set窗口中的实例都会失去其类型信息,当我们要取出数据进行使用时,就必须再手动强制转换回它们原来的类型。如果我们忘记了它们是什么类型的对象,那就费时了。。慢慢拉上去翻前面的代码吧。。。
2、定义泛型类
为了解决传统的泛型设计用Object定义类所带来的种种问题(如类型丢失、程序员忘记了转换类型、必须将其转换为原来的类型才能调用相应的方法),Java在J2SE 5.0之后提出了针对泛型设计的解决方案。
如:下面的代码用泛型类取代了Object :
// 在类名后面,使用来声明一个类型持有者(Holder)
public class Demo
{
private T obj;
public void setObj(T obj)
{
this.obj = obj;
}
public T getObj()
{
return obj;
}
}
使用泛型定义类时,可以用
Demo obj = new Demo();
这样,在调用getObj()方法时,返回的就会是一个我们在尖括号内所指定的Integet对象,而不是Object了,因此也就不必再进行类型转换了:
obj.setObj(new Integer(100));
Integer I = obj.getObj(); //无需强制转换
如果我们使用泛型类声明对象的时候没有为它指定类型,那么 编译器默认会使用Object类型。这样的话我们就得又要像之前那样进行类型转换了。
3、几个泛型的小例子
我们可以在定义泛型类时,同时声明多个类型持有者,如:
class Test //声明了两个Holder
{
private T1 obj1;
private T2 obj2;
public Test(T1 obj1,T2 obj2)
{
this.obj1 = obj1;
this.obj2 = obj2;
}
}
也可以声明数组,如:
class TestArray
{
// 声明T类型的数组
private T[] objs;
public TestArray(T[] objs)
{
this.objs = objs;
}
}
但要注意的是,不允许使用泛型来建立数组的实例,如下面的操作是错误的:
class TestArray
{
// 声明T类型的数组
private T[] objs = new T[10]; //Error
public TestArray(T[] objs)
{
this.objs = objs;
}
}
了解了以上知识,我们就可以在实际中应用泛型类了。在下一节中我们会介绍Java中泛型的高级语法。