Java泛型简介

来源:互联网 发布:ubuntu更新 编辑:程序博客网 时间:2024/06/12 23:43

1       泛型

1.1      泛型的概念

泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。

上面这段话不长,但读一遍能让人把舌头嚼烂,所以我给泛型下了另一个简单好理解的定义:

可以把泛型看作是类声明的占位符,在不确定某处该用什么类的时候,用泛型来代替原本要写在这里的类名。

1.2      泛型的作用

消除代码中的强制类型转换,同时获得一个附加的类型检查层,这是泛型所作的工作。

泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。

不好理解是吧?我们还是举例说明,首先看个不使用泛型的例子:



再看使用泛型的例子:



如果试图给clazz赋个与T不兼容的类型,编译器就会报错,大大提高了类型转换的安全性。

也就是说,使用泛型使得一些运行期才能发现的类型转换错误,提前到编译期就能发现,这就是泛型的好处。

1.3      泛型的定义

1.3.1     定义泛型类

在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数。在类里面,类型参数几乎可以用于任何可以使用类名的地方。

请看例子:



当声明或者实例化一个泛型的对象时,必须指定类型参数的值。就好比一把万用螺丝刀,没装刀头的时候就是个废物,只能用来砸花花草草小朋友什么的。

还是来看例子:



1.3.2     定义泛型方法

方法也可以被泛型化,不管它们定义在其中的类是不是泛型化的。

看例子:



为什么选择定义泛型方法,而不是定义泛型类呢?至少有两种情况应该这样做:

当泛型方法是静态的时,这种情况下不能使用类类型参数;

当类中只有一个方法需要用到泛型时。

1.3.3     命名类型参数

推荐的命名约定是使用大写的单个字母名称作为类型参数。反映了大多数泛型类将具有少量类型参数的假定。对于常见的泛型模式,推荐的名称是:

K ——键,比如映射的键。

V ——值,比如 List Set 的内容,或者 Map中的值。

E ——异常类。

T ——泛型。

1.4      泛型的约束

1.4.1     泛型不是协变的

一个常见的关于泛型的混淆就是假设它们像数组一样是协变的。其实它们不是协变的。GenericSample<Object>不是GenericSample <String> 的父类型。

请看例子:



1.4.2     类型通配符

解决这个问题的办法之一是使用类型通配符,请看下面的例子:




上面代码中的“?”是一个类型通配符。GenericSample<?>是任何泛型GenericSample的父类型,所以您完全可以将GenericSample <Object>GenericSample <Integer>传递给GenericSample<?>

使用通配符受到编译器的一些限制,请看下面的例子:




在上面的例子中,编译器不能对GenericSample的类型参数<?>作出足够严密的推理,以确定将Object传递给genericResign方法是类型安全的,所以编译器将不允许您这么做。

1.4.3     定义和创建泛型数组

直接看例子:




这似乎是分配后备数组最自然的一种方式,但是不幸的是,您不能这样做。以下是创建泛型数组的正确方式:




为什么会这么别扭?这是一个很长的故事,泛型本不是Java与生俱来的特性,是在J2SE 1.5版才加入的。为了加入泛型,Sun公司的程序员们一咬牙一跺脚,愣是把全部集合类都重写了,什么开闭原则都不顾了。但是涉及到JVM的存储堆栈管理,他们还是慎重了一把,没敢动的太狠,所以才造成这种古怪的局面。“等待以后的版本改进吧,那时候我TM早跳槽去谷歌了!”Sun公司的程序员大概是这样想的。



佛争一柱香,我要你打赏

0 0
原创粉丝点击