java泛型

J2 SE1.5中的特性
收藏
0有用+1
0
Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 [1]
中文名
Java泛型
外文名
Java generics
软件语言
Java
适用版本
Java SE 1.5以上
特    点
运行效率高等
所属领域
计算机科学技术

提出背景

播报
编辑
Ja棕备慨va集合(Collection)中元素的类型是多种多样的。例如,有些集合中的元素是Byte类型的,而有些则可能是String类型的,等等。Java允许程序员构建一个元素类型为Object的C地旬宙ollection,其中的元素可以是任何类型在Java SE 1.5之前,没乃协有泛型(Generics)的情况下,通过对类型O辨只bject的引用来实现参数的“任意夜汗弃企纹设定化”,“任意化”带来的缺点是要作显式的强制类型转换,而这种转换是要求开发者对实际参数类型可骗洪狱以在预乐敬颂知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。因此,为了解决这一问题,J2SE 1.5引入泛型也是自然而然的了。 [1]

发展概况

播报
编辑
Sun JDK的泛型发展要从1.3版本说起,他配合GJ,正式进入泛型殿堂。GJ是“Generic Java”的缩写,是一个支援泛型的Java编译器补充件,是Java泛型技术的先驱。随后,泛型议题正式成为JSR#14,其技术基础便是源自GJ。JDK1.4搭配JSR14提供的外挂附件,使泛型技术在Java世界成为众所瞩目的焦点。
2004年夏天,Sun公司发布了Java编程语言的重大修改版。该版本代号取名为“Tiger”,官方名称为JDK1.5。JDK1.5相对于JDK1.3至JDK 1.4之间变化幅度大很多,它将在运行时性能(runtime performance)、可扩缩性(scalability)、易管理性(manageability)和监控(monitoring)方面有较大加强;此外,还增加了许多激动人心的新的语言特性。泛型就是其中之一。JDK 1.5内建泛型特征,不仅编译器不再需要任何外力(外挂附件)的帮助,整个Java标准程式库也被翻新,许多角落针对泛型做了改写。 [2]

作用

播报
编辑
第一是泛化。可以用T代表任意类型Java语言中引入泛型是一个较大的功能增强不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了,这带来了很多好处。
第二是类型安全。泛型的一个主要目标就是提高Java程序的类型安全,使用泛型可以使编译器知道变量的类型限制,进而可以在更高程度上验证类型假设。如果不用泛型,则必须使用强制类型转换,而强制类型转换不安全,在运行期可能发生ClassCast Exception异常,如果使用泛型,则会在编译期就能发现该错误。
第三是消除强制类型转换。泛型可以消除源代码中的许多强制类型转换,这样可以使代码更加可读,并减少出错的机会。
第四是向后兼容。支持泛型的Java编译器(例如JDK1.5中的Javac)可以用来编译经过泛型扩充的Java程序(Generics Java程序),但是现有的没有使用泛型扩充的Java程序仍然可以用这些编译器来编译。 [1]

泛型使用

播报
编辑
1、泛型类和泛型接口
如果定义的一个类或接口有一个或多个类型变量,则可以使用泛型。泛型类型变量由尖括号界定,放在类或接口名的后面,下面定义尖括号中的T称为类型变量。意味着一个变量将被一个类型替代替代类型变量的值将被当作参数或返回类型。对于List接口来说,当一个实例被创建以后,T将被当作一个函数的参数下面分别是泛型类、泛型接口的定义:
public class Gen<T>{/泛型类 …… }
public interface List<T> extends Collection<T>{//泛型接口 …… }
2、泛型方法
是否拥有泛型方法,与其所在的类是否泛型无关。
要定义泛型方法,只需将泛型参数列表置于返回值前。
如:
public class ExampleA{     public<> voidf(Tx){         System.out.println(x.getClass().get Name());     }     publiec static void main(String args[ ]){     ExampleA ea= new ExampleA();         ea-f("");         ea.f(10);         ea.f(a);         ea.f(ea);     } }
使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。 [1]

优点

播报
编辑
Java语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了很大的改动,许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处:
1、类型安全
泛型的主要目标是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在非常高的层次上验证类型假设。没有泛型,这些假设就只存在于系统开发人员的头脑中。
通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误就可以在编译时被捕获了,而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于Java开发人员更早、更容易地找到错误,并可提高程序的可靠性。
2、消除强制类型转换
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以提高使用泛型类的代码的累赞程度,但是声明泛型变量时却会带来相应的累赞程度。在简单的程序中使用一次泛型变量不会降低代码累赞程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低累赞程度。所以泛型消除了强制类型转换之后,会使得代码加清晰和筒洁。
3、更高的运行效率
在非泛型编程中,将筒单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显。
4、潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM的优化带来可能。 [3]

使用注意事项

播报
编辑
使用Java泛型应该注意如下几点:
①在定义一个泛型类时,在“<>”之间定义形式类型参数,例如:“class TestGen<K,V>”,其中“K”,“V”不代表值,而是表示类型。
②实例化泛型对象时,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。
③泛型中<Kextends ObjecD,extends>并不代表继承,它是类型范围限制。
④使用泛型时,泛型类型必须为引用数据类型,不能为基本数据类型,Java中的普通方法,构造方法,静态方法中都可以使用泛型,方法使用泛型之前必须先对泛型进行声明,可以使用任意字母,一般都要大写。
⑤不可以用一个本地类型(如int float)来替换泛型。
⑥运行时类型检查,不同类型的泛型类是等价的(Pair与Pair是属于同一个类型Pair),这一点要特别注意,即如果obj instance of Pai == true的话,并不代表objget First()的返回值是一个String类型。
⑦泛型类不可以继承Exception类,即泛型类不可以作为异常被抛出。
⑧不可以定义泛型数组。
⑨不可以用泛型构造对象,即:first = new T();是错误的。
⑩在static方法中不可以使用泛型,泛型变量也不可以用static关键字来修饰
⑪不要在泛型类中定义equals(Tx)这类方法,因为Object类中也有equals方法,当泛型类被擦除后,这两个方法会冲突。
⑫根据同一个泛型类衍生出来的多个类之间没有任何关系,不可以互相赋值。
⑬若某个泛型类还有同名的非泛型类,不要混合使用,坚持使用泛型类。 [1]