一.类型参数形态
按照泛型类型参数的表现形态,先列出所有可能出现的,再来归纳,以List为例:
- Holder:原生态类型
- Holder<T>:最简单的泛型形态。
- Holder<T extends Number>:有限制形式类型参数。
- Holder<T super Number>:有限制形式类型参数。可惜的是没有这种语法。
- Holder<? extends T>:子类型通配符。
- Holder<? super T>:超类型通配符。
- Holder<?>:无界限定符。
- Holder<Object>:同List。
二.有限制形式类型参数
Holder<T extends Number>,实际参数类型将只能是Number的子类型。
三.通配符
- 子类型通配符:能读不能写。我知道Holder里持有的永远是T的子类,所以get必定就是T类型;但我只知道是T的子类型,但具体是什么,没法确定,为了保证类型安全,不允许set,当然能set(null),因为null恰好不需要类型。
- 超类型通配符:能写不能读。我知道Holder里持有的永远是T的超类,那我set一个T类型的对象当然是可以的(T的子类当然也可以),当然set(null)也完全没问题;但到底是哪个超类呢,不确定,所以get操作类型是不确定的,只能get出一个Object。
- 无界通配符:不能读不能写。没有任何界限,我永远不知道用户想使用一个什么类型,get操作也只能get出一个Object,set操作只能set一个null。
- 总结:PECS produces-extends, consumer-super。produces && consumer请使用原生类型。
package com.jyz.study.jdk.generic; /** * 通配符 * @author JoyoungZhang@gmail.com * */ public class Wildcards { //原生类型 static void rawArgs(Holder holder, Object arg){ holder.get(); holder.set(arg); holder.set(new Wildcards()); } //无界通配符 static void unboundedArg(Holder<?> holder, Object arg){ Object object = holder.get(); T t = holder.get();//compile error, don't hava any T holder.set(arg);//compile error holder.set(null); } //子类型通配符 static <T> T wildSubtype(Holder<? extends T> holder, T arg){ holder.set(arg);//compile error holder.set(null); T t = holder.get(); return t; } //超类型通配符 static <T> T wildSupertype(Holder<? super T> holder, T arg){ holder.set(arg); holder.set(null); T t = holder.get();//compile error Object obj = holder.get(); return t; } class Holder<T> { private T element; public Holder() { } public Holder(T element) { this.element = element; } public T get(){ return element; } public void set(T arg){ this.element = arg; } public boolean equals(Object obj){ if(!(obj instanceof Holder)){ return false; } Holder<?> holder = (Holder<?>)obj; return element == null ? holder.element == null : element.equals(holder.element); } } }
四.四者区别
- List:原生类型,没有泛型存在,List存在的是Object类型,取出来也是Object类型,需要自己做类型转换。
- List<Object>:List实际上就是List<Object>,我觉得没必要显示的来说明一下List<Object>。
- List<?>:具有某种特定类型的非原生List,只是这个类型还不确定,将有使用者去确定。确定后,就永远存在这个类型的对象,取出来也是这个类型的变量。
- List<? extends Object>:具有某种特定类型的非原生List,这个类型也还不确定,将有使用者去确定,并且,这个类型必须是Object的子类。因为恰好Java里任何类都是Object的子类,所以我觉得List<? extends Object>意义不大,使用List<?>足够了,如果换成List<? extends Number>这个语法才能发挥威力。
五.什么使用T 什么时候使用?
- 定义一个泛型类或泛型接口时,使用<T> <T extends 具体类型>。
- 引用泛型类时,使用<?> <? extends T> <? super T>。一般是将泛型类或接口定义成一个变量(成员变量和局部变量),或将泛型类或接口作为返回值时。
- 下面这个泛型类差不多涵盖了泛型最复杂的表现形态。能轻松写出来,使用泛型对你来说就是小事了。
package com.jyz.study.jdk.generic; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 什么时候用T 什么时候用? * @author JoyoungZhang@gmail.com * http://zy19982004.iteye.com/blog/1978028 * */ public class TOrQuestionMark<TT> { protected Holder<? extends Throwable> list1; protected Holder<? super Throwable> list2; private Holder<? extends Throwable> test1(Holder<? extends Throwable> list){ return list; } private Holder<? super Throwable> test2(Holder<? super Throwable> list){ return list; } protected List<? extends TT> list3; protected List<? super TT> list4; protected List<? extends TT> test3(List<? extends TT> list){ return list; } protected List<? super TT> test4(List<? super TT> list){ return list; } public void init() { list1 = new Holder<RuntimeException>(); list1 = new Holder<IOException>(); list2 = new Holder<Throwable>();//没办法Throwable已经没有超类了,用自己 Holder<? extends Throwable> listreturn1 = test1(new Holder<IOException>()); Holder<? super Throwable> listreturn2 = test2(new Holder<Throwable>()); //以下依赖TT,先实例化tq TOrQuestionMark<Exception> tq = new TOrQuestionMark<Exception>(); tq.list3 = new ArrayList<RuntimeException>(); tq.list3 = new ArrayList<IOException>(); tq.list4 = new ArrayList<Throwable>(); List<? extends Exception> listreturn3 = tq.test3(new ArrayList<RuntimeException>()); List<? super Exception> listreturn4 = tq.test4(new ArrayList<Throwable>()); } } class Holder<T extends Throwable>{ private T obj; public void set(T obj){ this.obj = obj; } public T get(){ return obj; } } //sorry,compile error!!!!! //class Holder2<T super IOException>{ // private T obj; // public void set(T obj){ // this.obj = obj; // } // public T get(){ // return obj; // } //}
相关推荐
2. JAVA的继承和多态:JAVA支持继承和多态,继承可以实现代码的重用,多态可以实现方法的多种形态。 3. JAVA的封装和抽象:JAVA支持封装和抽象,封装可以隐藏对象的内部实现,抽象可以定义接口和抽象类。 三、多...
Java学习资料的目的是帮助你深入理解其核心概念,并逐步精通Java编程。以下是对Java学习的重要知识点的详细阐述: 1. **Java基础**:首先,你需要了解Java的基础语法,包括变量、数据类型、运算符、流程控制(如if...
10. **泛型**:泛型是Java 5引入的新特性,增强了类型安全性,避免了类型转换的麻烦。 11. **接口与模块系统**:Java 8引入了默认方法,Java 9引入了模块系统,这两者都提升了接口的灵活性和代码组织结构。 12. **...
"Java入门(实例学习)"的资源集旨在帮助初学者通过实际操作深入理解Java编程的基本概念和语法。在这个压缩包中,包含了一系列精心设计的Java实例,每一个都经过了编译验证,确保可以运行并展示特定的编程概念。 1....
9. **泛型**:泛型是Java SE 5.0引入的新特性,用于增强类型安全,减少类型转换,并消除运行时的ClassCastException。 10. **反射**:Java反射机制允许在运行时检查类、接口、字段和方法的信息,甚至可以在运行时...
"Java学习代码"这个标题表明了资源的内容,主要是用于教学或自我学习Java编程的基础示例。描述中的“有意者请下载”暗示了这些代码可能是为了帮助初学者理解和实践Java编程概念。 在Java学习过程中,通常会通过编写...
多态则是指同一种行为在不同对象上表现出来的不同形态。 3. **接口与抽象类**:Java中的接口和抽象类是实现多态的重要方式。接口定义了一组方法,但不包含具体实现,而抽象类可以包含部分或全部方法的实现。 4. **...
9. **泛型**:Java泛型提供了类型安全,可以在编译时检查类型错误。源码中的泛型使用能帮助理解如何编写更安全、更具可读性的代码。 10. **接口与抽象类**:接口用于定义行为规范,抽象类则提供部分实现。源码中的...
通过实践这些代码,学习者可以更好地理解和应用Java的核心概念。 1. **基本语法**:Java的基本语法包括变量声明、数据类型(如整型、浮点型、字符型和布尔型)、运算符(如算术、比较和逻辑运算符)、流程控制语句...
10. **泛型**:Java泛型提供了一种方式来限制容器对象只能存储特定类型的数据,提高了代码的类型安全性和重用性。 以上知识点构成了Java语言的核心部分,通过学习《Java语言规范(第三版)》,开发者能够更深入地理解...
多态则提供了多种形态的能力,使得子类可以有不同的表现形式。 4. **异常处理**:Java中的异常处理机制帮助程序在遇到错误时能够优雅地进行处理,通过try-catch-finally语句块捕获和处理异常,确保程序的健壮性。 ...
8. **泛型**:自Java 5.0引入,泛型提供了一种在编译时确保类型安全的方法,允许在集合和其他容器中存储特定类型的元素。 9. **枚举类型**:Java 5.0引入的枚举类型,用于表示一组固定的常量,提高了代码的可读性和...
"java核心技术与java资料"这个主题涵盖了Java语言的核心概念和技术,以及与之相关的学习资源。 Java核心技术主要包括以下几个方面: 1. **基础语法**:Java的基础语法包括变量、数据类型、运算符、流程控制(如if...
PDF文档"JAVA核心知识点整理.pdf"可能涵盖了以下几个重要的Java学习主题: 1. **Java基础**:这部分通常包括Java的历史背景、环境配置、程序结构(如主方法)、基本数据类型、变量、运算符、流程控制(if-else、...
《Java2全方位学习》是一本深受程序员喜爱的书籍,它涵盖了Java编程语言的各个方面,旨在帮助读者从初学者到熟练者全面掌握Java技术。这本书的源代码提供了丰富的实例,让读者能够通过实践来深化理解书中的理论知识...
多态则是指同一种行为在不同对象上表现出不同的形态,是面向对象的重要特性。 4. **异常处理**:Java提供了异常处理机制来捕获和处理运行时错误,使用try-catch-finally语句块来管理可能出现的异常情况。 5. **...
压缩包中的"corejava核心技術九版"可能是指《Java核心技术》的第九版,该书详细介绍了上述的Java核心概念和技术,覆盖了从基础到高级的主题,是学习和提升Java技能的优秀教材。通过阅读这本书,开发者能够深入理解...
在本压缩包“《java课程设计》第十三周学习总结doc文档合集整理.zip”中,我们可以看到聚焦于Java编程语言的学习与应用。这个资源集合是针对Java课程设计的第十三周学习成果的汇总,旨在帮助学生巩固所学知识,提升...
这个"Java语言程序设计基础篇源代码"涵盖了初学者在学习Java编程时需要掌握的基本概念、语法和技巧。以下是对这些源代码文件的详细解读: 1. **基本语法**:Java是一种静态类型的面向对象的语言,它要求在编写程序...
【便捷资料1234567.rar】这个压缩包文件显然包含了与Java编程语言相关的学习资源。在Java的世界里,有许多重要的知识点等待我们去探索。以下是一些关键的Java编程概念和相关技术: 1. **Java基础**:Java是一种面向...