泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。

规则和限制

1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。
5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String")。

限制泛型
我们一般是这样定义泛型的:class Generics<T>,实际上这里的限定类型相当于Object,这和“Object泛型”实质是一样的。什么是限制比如我们要限制T为集合接口类型。只需要这么做:class Generics<T extends Collection>,这样类中的泛型T只能是Collection接口的实现类,传入非Collection接口编译会出错。

注意:<T extends Collection>这里的限定使用关键字extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。

public class CollectionGen<T extends Collection> {
private T t; public CollectionGen(T t) {
this.t = t;
} public T getT() {
return t;
} public void setT(T t) {
this.t = t;
} public static void main(String args[]) {
CollectionGen<ArrayList> genList = null;
genList = new CollectionGen<ArrayList>(new ArrayList()); //以下代码不能通过编译
// CollectionGen<Collection> genCollention = null;
// genCollention=new CollectionGen<ArrayList>(new ArrayList());
System.out.println("可以编译通过并运行!");
}
}

上面的代码是可以编译通过并成功运行的。但是打开注释掉的两行就出错了,因为<T extends Collection>这么定义类型的时候,就限定了构造此类实例的时候T是确定的一个类型,这个类型实现了Collection接口。简单一句话就是:上面这种方式,定义跟实例化的类型必须完全一致。

通配符泛型
为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了“通配符泛型”,针对上面的例子,使用通配泛型格式为<? extends Collection>,“?”代表未知类型,这个类型是实现Collection接口。那么上面实现的方式可以写为:

public static void main(String args[]) {
Generics<ArrayList> genList = null;
genList = new Generics<ArrayList>(new ArrayList()); //以下代码可以通过编译
Generics<? extends Collection> genCollention = null;
genCollention=new Generics<ArrayList>(new ArrayList());
System.out.println("可以编译通过并运行!");
}

1、如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。
2、通配符泛型不单可以向下限制,如<? extends Collection>,还可以向上限制,如<? super Double>,表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
3、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似。

多接口限制
虽然Java泛型简单的用 extends 统一的表示了原有的 extends 和 implements 的概念,但仍要遵循应用的体系,Java 只能继承一个类,但可以实现多个接口,所以你的某个类型需要用 extends 限定,且有多种类型的时候,只能存在一个是类,并且类写在第一位,接口列在后面,也就是:<T extends SomeClass & interface1 & interface2 & interface3>

这里的例子仅演示了泛型方法的类型限定,对于泛型类中类型参数的限制用完全一样的规则,只是加在类声明的头部,如:

public class Demo<T extends Comparable & Serializable>{
//T类型就可以用Comparable声明的方法和Seriablizable所拥有的特性了
}

最后再强调一点,就是泛型最重要的作用就是提高了代码的安全性,因为它能够在编译期对代码进行检查,从而避免了很多在运行期强转类型发生的异常。了解了泛型出现的目的,相信你也就知道该怎么使用泛型了吧!

最新文章

  1. 扩大a标签的响应区域
  2. js日期时间比较函数
  3. Oracle SQL Tips
  4. Google protobuf
  5. Bzoj 1984: 月下“毛景树” 树链剖分
  6. LeetCode——Climbing Stairs
  7. 【ALB学习笔记】基于事件触发方式的串行通信接口数据接收案例
  8. Python内置函数(35)——next
  9. web领域的实时推送技术-WebSocket
  10. 【转】How to create a new user and grant permissions in MySQL
  11. 百度EasyDL文本分类自定义API示例代码 python
  12. 性能调优8:分组聚合 - group by
  13. qml: 支持的基本类型
  14. 安装rcssmin方法
  15. Bitmap RGB24 4字节对齐
  16. PHP合并数组
  17. DNS之BIND使用小结(Forward转发)
  18. 在Unity中使用Lua脚本
  19. jenkins构建时报错
  20. 洛谷 P2089 烤鸡

热门文章

  1. 【Java】 剑指offer(13) 剪绳子
  2. dp的最优性
  3. 仿win10环境变量助手
  4. 解决sublime text 安装扩展提示There are no packages available for installation问题
  5. SpringMvc 文件下载 详解
  6. PHP文本处理 中文汉字字符串 转换为数组
  7. django——inclusion_tag
  8. wamp memcache 的安装与扩展(Windows 64)
  9. 用单片机控制LED灯(项目)
  10. iOS埋点统计