`
zy19982004
  • 浏览: 661792 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
F6f66edc-1c1a-3859-b76b-a22e740b7aa7
Hadoop学习
浏览量:251950
社区版块
存档分类
最新评论

Java泛型学习三:泛型的表现形态

 
阅读更多

一.类型参数形态

     按照泛型类型参数的表现形态,先列出所有可能出现的,再来归纳,以List为例:

  1. Holder:原生态类型
  2. Holder<T>:最简单的泛型形态。
  3. Holder<T extends Number>:有限制形式类型参数。
  4. Holder<T super Number>:有限制形式类型参数。可惜的是没有这种语法。
  5. Holder<? extends T>:子类型通配符。
  6. Holder<? super T>:超类型通配符。
  7. Holder<?>:无界限定符。
  8. Holder<Object>:同List。

 

二.有限制形式类型参数

      Holder<T extends Number>,实际参数类型将只能是Number的子类型。

 

三.通配符

  1. 子类型通配符:能读不能写。我知道Holder里持有的永远是T的子类,所以get必定就是T类型;但我只知道是T的子类型,但具体是什么,没法确定,为了保证类型安全,不允许set,当然能set(null),因为null恰好不需要类型。
  2. 超类型通配符:能写不能读。我知道Holder里持有的永远是T的超类,那我set一个T类型的对象当然是可以的(T的子类当然也可以),当然set(null)也完全没问题;但到底是哪个超类呢,不确定,所以get操作类型是不确定的,只能get出一个Object。
  3. 无界通配符:不能读不能写。没有任何界限,我永远不知道用户想使用一个什么类型,get操作也只能get出一个Object,set操作只能set一个null。
  4. 总结: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);
    		}
    	}
    }
    
      

四.四者区别

  1. List:原生类型,没有泛型存在,List存在的是Object类型,取出来也是Object类型,需要自己做类型转换。
  2. List<Object>:List实际上就是List<Object>,我觉得没必要显示的来说明一下List<Object>。
  3. List<?>:具有某种特定类型的非原生List,只是这个类型还不确定,将有使用者去确定。确定后,就永远存在这个类型的对象,取出来也是这个类型的变量。
  4. List<? extends Object>:具有某种特定类型的非原生List,这个类型也还不确定,将有使用者去确定,并且,这个类型必须是Object的子类。因为恰好Java里任何类都是Object的子类,所以我觉得List<? extends Object>意义不大,使用List<?>足够了,如果换成List<? extends Number>这个语法才能发挥威力。

五.什么使用T 什么时候使用?

  1. 定义一个泛型类或泛型接口时,使用<T> <T extends 具体类型>。
  2. 引用泛型类时,使用<?> <? extends T> <? super T>。一般是将泛型类或接口定义成一个变量(成员变量和局部变量),或将泛型类或接口作为返回值时。
  3. 下面这个泛型类差不多涵盖了泛型最复杂的表现形态。能轻松写出来,使用泛型对你来说就是小事了。
    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;
    //	}
    //}
    
     
0
0
分享到:
评论

相关推荐

    华为综合面试题集及感受

    2. JAVA的继承和多态:JAVA支持继承和多态,继承可以实现代码的重用,多态可以实现方法的多种形态。 3. JAVA的封装和抽象:JAVA支持封装和抽象,封装可以隐藏对象的内部实现,抽象可以定义接口和抽象类。 三、多...

    Java学习资料 开始重新系统学习一下JAVA内容

    Java学习资料的目的是帮助你深入理解其核心概念,并逐步精通Java编程。以下是对Java学习的重要知识点的详细阐述: 1. **Java基础**:首先,你需要了解Java的基础语法,包括变量、数据类型、运算符、流程控制(如if...

    Java学习材料(499篇文章)--经典的java学习资料

    10. **泛型**:泛型是Java 5引入的新特性,增强了类型安全性,避免了类型转换的麻烦。 11. **接口与模块系统**:Java 8引入了默认方法,Java 9引入了模块系统,这两者都提升了接口的灵活性和代码组织结构。 12. **...

    Java入门(实例学习)

    "Java入门(实例学习)"的资源集旨在帮助初学者通过实际操作深入理解Java编程的基本概念和语法。在这个压缩包中,包含了一系列精心设计的Java实例,每一个都经过了编译验证,确保可以运行并展示特定的编程概念。 1....

    java学习代码

    9. **泛型**:泛型是Java SE 5.0引入的新特性,用于增强类型安全,减少类型转换,并消除运行时的ClassCastException。 10. **反射**:Java反射机制允许在运行时检查类、接口、字段和方法的信息,甚至可以在运行时...

    java 学习代码这些是一些基础例子

    "Java学习代码"这个标题表明了资源的内容,主要是用于教学或自我学习Java编程的基础示例。描述中的“有意者请下载”暗示了这些代码可能是为了帮助初学者理解和实践Java编程概念。 在Java学习过程中,通常会通过编写...

    thinking in java 文档

    多态则是指同一种行为在不同对象上表现出来的不同形态。 3. **接口与抽象类**:Java中的接口和抽象类是实现多态的重要方式。接口定义了一组方法,但不包含具体实现,而抽象类可以包含部分或全部方法的实现。 4. **...

    Java学习手册-源码

    9. **泛型**:Java泛型提供了类型安全,可以在编译时检查类型错误。源码中的泛型使用能帮助理解如何编写更安全、更具可读性的代码。 10. **接口与抽象类**:接口用于定义行为规范,抽象类则提供部分实现。源码中的...

    java基础练习代码

    通过实践这些代码,学习者可以更好地理解和应用Java的核心概念。 1. **基本语法**:Java的基本语法包括变量声明、数据类型(如整型、浮点型、字符型和布尔型)、运算符(如算术、比较和逻辑运算符)、流程控制语句...

    Java语言规范(第三版)

    10. **泛型**:Java泛型提供了一种方式来限制容器对象只能存储特定类型的数据,提高了代码的类型安全性和重用性。 以上知识点构成了Java语言的核心部分,通过学习《Java语言规范(第三版)》,开发者能够更深入地理解...

    Absolute Java

    多态则提供了多种形态的能力,使得子类可以有不同的表现形式。 4. **异常处理**:Java中的异常处理机制帮助程序在遇到错误时能够优雅地进行处理,通过try-catch-finally语句块捕获和处理异常,确保程序的健壮性。 ...

    java语言规范第三版html

    8. **泛型**:自Java 5.0引入,泛型提供了一种在编译时确保类型安全的方法,允许在集合和其他容器中存储特定类型的元素。 9. **枚举类型**:Java 5.0引入的枚举类型,用于表示一组固定的常量,提高了代码的可读性和...

    java核心技术与java资料

    "java核心技术与java资料"这个主题涵盖了Java语言的核心概念和技术,以及与之相关的学习资源。 Java核心技术主要包括以下几个方面: 1. **基础语法**:Java的基础语法包括变量、数据类型、运算符、流程控制(如if...

    JAVA核心知识点整理.rar

    PDF文档"JAVA核心知识点整理.pdf"可能涵盖了以下几个重要的Java学习主题: 1. **Java基础**:这部分通常包括Java的历史背景、环境配置、程序结构(如主方法)、基本数据类型、变量、运算符、流程控制(if-else、...

    《java2全方位学习》源代码

    《Java2全方位学习》是一本深受程序员喜爱的书籍,它涵盖了Java编程语言的各个方面,旨在帮助读者从初学者到熟练者全面掌握Java技术。这本书的源代码提供了丰富的实例,让读者能够通过实践来深化理解书中的理论知识...

    java基础pptrar

    多态则是指同一种行为在不同对象上表现出不同的形态,是面向对象的重要特性。 4. **异常处理**:Java提供了异常处理机制来捕获和处理运行时错误,使用try-catch-finally语句块来管理可能出现的异常情况。 5. **...

    corejava java core

    压缩包中的"corejava核心技術九版"可能是指《Java核心技术》的第九版,该书详细介绍了上述的Java核心概念和技术,覆盖了从基础到高级的主题,是学习和提升Java技能的优秀教材。通过阅读这本书,开发者能够深入理解...

    《java课程设计》第十三周学习总结doc文档合集整理.zip

    在本压缩包“《java课程设计》第十三周学习总结doc文档合集整理.zip”中,我们可以看到聚焦于Java编程语言的学习与应用。这个资源集合是针对Java课程设计的第十三周学习成果的汇总,旨在帮助学生巩固所学知识,提升...

    Java语言程序设计基础篇源代码

    这个"Java语言程序设计基础篇源代码"涵盖了初学者在学习Java编程时需要掌握的基本概念、语法和技巧。以下是对这些源代码文件的详细解读: 1. **基本语法**:Java是一种静态类型的面向对象的语言,它要求在编写程序...

    便捷资料1234567.rar

    【便捷资料1234567.rar】这个压缩包文件显然包含了与Java编程语言相关的学习资源。在Java的世界里,有许多重要的知识点等待我们去探索。以下是一些关键的Java编程概念和相关技术: 1. **Java基础**:Java是一种面向...

Global site tag (gtag.js) - Google Analytics