一、代码重用性、可读性好
首先我们看两个例子:
public class StringVaa
{
private String vaa;
public void setVaa(String vaa){this.vaa = vaa;}
public String getVaa(){return vaa;}
}
public class IntegerVaa
{
private Integervaa;
public void setVaa(Integer vaa){this.vaa = vaa;}
public Integer getVaa(){return vaa;}
}
观察范例StringVaa与IntegerVaa两个类,其中除了声明成员的类型、参数行的类型与方法返回值的类型不同之外,剩下的程序代码完全相同。或许有些程序员会将第一个类的内容复制到第二个文件中,然后用编辑器的取代功能一次取代所有的类型名称(即将String取代为Integer),但当类中的逻辑要修改,就需要修改两个文件。而类似的功能,用上文中GenericVaa泛型类来实现,能使代码更清晰、简洁,减少文件管理困扰。
二、消除强制类型转换
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。由于Java中所有的类最上层都继承自Object类,所以可以定义ObjectVaa类来取代StringVaa和IntegerVaa两个类。
public class ObjectVaa
{
private Object vaa;
public void setVaa(Object vaa){this.vaa = vaa;}
public Object getVaa(){return vaa;}
}
在JDK1.5之前版本,大部分开发人员都会通过上面这种方法来简化代码,并按照下面方法来使用。
ObjectVaa vaa1 = new ObjectVaa();
ObjectVaa vaa2 = new ObjectVaa();
vaa1.setVaa(new String("Hello!"));
vaa2.setVaa(new Integer(8));
//记得类型转换
String s = (String)vaa1.getVaa();
Integer i = (Integer)vaa2.getVaa();
这种实现方法虽然对代码做了一定的简化,但是创建vaa1和vaa2两个实例时,都失去了类型信息,从getVaa()返回的是Object类型的实例,必须转换为它的实现类型(即强制类型转换)才能获得实现类型的类型信息。而利用Gener-icVaa泛型类来实现,在上文Gener-icVaaDemo类中使用时,就不需要进行类型的强制转换。
三、类型安全
提高Java程序的类型安全是泛型的主要目标。上文中的ObjectVaa类在使用时,常需要强制的类型转换,然而程序设计人员往往会忘了要做这个动作,更严重的是转换类型时会用错了型(如用String却用了Integer)。例如:
ObjectVaa vaa1 = newObjectVaa();
vaa1.setVaa(new String("Hello!"));
Integer i = (Integer)vaa1.getVaa();
由于语法上并没有错误,编译器检查不出上面的程序有错误,真正的错误要在执行时期才会发生,这时就会抛出ClassCastException异常。而 泛型类则将类型检查从运行时挪到编译时,例如:
GenericVaa<String> gStr = new GenericVaa<String>();
gStr.setVaa(new String("Hello!"));
Integer i = gStr.getVaa();
gStr使用getVaa()方法返回的就是声明对象时在<>中所指定的String类型的实例,若要将这个实例指定给Integer类型的变量,显然在语法上不合,编译器这时检查出错误:
GenericVaaDemo.java:6:不兼容的类型
找到:java.lang.String
需要:java.lang.Integer
Integers = gStr.getVaa();
利用泛型类来实现,有助于Java开发人员更早、更容易地找到错误,并可提高程序的可靠性。
四、更高的运行效率
在非泛型编程中,将简单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显。
五、潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM的优化带来可能。
Java泛型让不同的数据类型可以共享算法,最主要的是它增强了程序的可读性和类型安全。把原来要等到运行时才可能被发现的一些安全隐患在编译期就暴露出来,如果使用得当,就可以大大提高程序的灵活性和健壮性。