- 浏览: 193058 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
asdiy:
very good!原来是这个原因!
为什么会"well-known file is not secure" ? -
豆浆王子:
...
在Struts2的Action中取得请求参数值的几种方法 -
key232323:
skyfen 写道LZ是个很棒的人,加油!
+1
我四年的职业生涯,2010路在何方? -
skyfen:
LZ是个很棒的人,加油!
我四年的职业生涯,2010路在何方? -
y112300:
天下乌鸦一般黑,怎一个乱子了得
我四年的职业生涯,2010路在何方?
java泛型从JDK1.5开始出来的,虽然自己平时也有用到,但是一直没有全面的学习,今天在看myibatis3.0.1源码时,看到多处用到泛型设计,所以自己把泛型学习了下。
什么是泛型?
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点就是被Object引用对象被“上塑”造型,对象的具体类型信息被丢失,这样当我们要使用该类型时要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
泛型使用的规则和限制
- 泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
- 同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
- 泛型的类型参数可以有多个。
- 泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。
- 泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");
泛型的基本使用
eg1:使用了泛型
package com.kyle.Generics.ch01; /** * 定义泛型类型 * @author kyle * * @param <T> */ public class SimpleDemo1<T> { private T ob;//定义泛型成员变量 public T getOb() { return ob; } public void setOb(T ob) { this.ob = ob; } public SimpleDemo1(T ob){ this.ob=ob; } public void showType(){ System.out.println("T的实际类型是:"+ob.getClass().getName()); } public static void main(String args[]){ //定义泛型SimpleDemo的一 个Integer版本 SimpleDemo1<Integer> intObj=new SimpleDemo1<Integer>(88); //不需要转换可以得到ob的具体类型 Integer intValue=intObj.getOb(); intObj.showType(); //定义泛型SimpleDemo的一个String版本 SimpleDemo1<String> strObj=new SimpleDemo1<String>("Hello world"); //不需要转换可以得到ob的具体类型 String strValue=strObj.getOb(); strObj.showType(); String str=strObj.getOb(); System.out.println("ob is vlaue :"+str); } }
eg2:没有使用泛型实现
package com.kyle.Generics.ch01; /** * 没有使用泛型 * @author kyle * */ public class SimpleDemo2{ private Object ob; //定义一个通用类型成员 public SimpleDemo2(Object ob) { this.ob = ob; } public Object getOb() { return ob; } public void setOb(Object ob) { this.ob = ob; } public void showType(){ System.out.println("Object的实际类型是:"+ob.getClass().getName()); } public static void main(String args[]){ SimpleDemo2 intObj=new SimpleDemo2(new Integer(88)); int intValue=(Integer)intObj; //强制转换成Integer intObj.showType(); SimpleDemo2 strObj=new SimpleDemo2(new String("Hello Gen2")); String strValue=(String)strObj;//强制转换成String strObj.showType(); } }
通过上面两个DEMO的比较,我们可以很直接的看到泛型给我们带来的易用性。在这里DEMO1中我们可以简单的假想为T就是我们构造对象时动态传入的字符串,例如
SimpleDemo1<Integer> intObj=new SimpleDemo1<Integer>(88)传入的是Integer,那么private T ob 就变成private Integer ob,SimpleDemo1<String> strObj=new SimpleDemo1<String>("Hello world")传入的String,那么private T ob就变成private String ob。T就相当于是一个类型变量,编译器在编译时把该变量替换成我们传入的类型。
泛型的高级应用
1.限制泛型的可用类型
class GenericsFoo<T extends Collection>,这样的泛型T只能是Collection接口的实现类或者子接口,传入非Collection接口则会编译报错
注意:<T extends Collection>这里的限定使用关键字extends ,实际T的类型Collection可以是实现Collection接口的类也可以是继承了Collection接口, extends只是起一个限定作用,而非继承的意义。
eg:
package com.kyle.Generics.ch03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
public class CollectionGenFoo <T extends Collection>{
private T x;
public CollectionGenFoo( T x){
this.x=x;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public static void main(String args[]){
/**1
* 定义CollectionGenFoo的泛型为ArrayList
* 即定义listFoo这个引用只接受泛型为
* ArrayList类型的实例
* 我们构造函数传入new ArrayList()传入的正是ArrayList类型
*/
CollectionGenFoo<ArrayList> listFoo = null;
listFoo=new CollectionGenFoo<ArrayList>(new ArrayList());
listFoo.getX();//该方法返回的对象为ArryList类型
/**2
* 定义CollectionGenFoo的泛型为Collection
* 即定义listFoo这个引用只接受泛型为
* Collection类型的实例
* 我们构造函数传入new ArrayList()是Collection接口的实现类
* 也是Collection类型的
*/
CollectionGenFoo<Collection> listFoo2 = null;
listFoo2=new CollectionGenFoo<Collection>(new ArrayList());
listFoo2.getX();//该方法返回的对象为Collection类型
/**3
* 下面的报错
*CollectionGenFoo<String>中的类型必须是 Collection类型的
*/
//CollectionGenFoo<String> listFoo3=null;
/**4
* 下面的报错,因为声明的引用已经定义参数必须为Collection类型的
* 那么new CollectionGenFoo<ArrayList>传入的类型必须与引用一致
* 即T这个类型变量不能同时为两个值
*/
//CollectionGenFoo<Collection> listFoo4 = null;
//listFoo4=new CollectionGenFoo<ArrayList>(new ArrayList());
}
}
通过这个例子,我们应该仔细对比1,2,3,4这三种声明方式,体会泛型的含义:
1.从1,2,3可以看出使用“有界泛型”<T extends SuperClass>这种声明方式 时,类型参数T必须是SuperClass的子类或者SuperClass类型。如果不是则会在编译时报:
Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends Collection> of the type CollectionGenFoo<T> 这个错误。
2.从4可以看出<T extends SuperClass>中的T虽然可以是任意SuperClass的任意类型,但是一旦引用指定具体类型以后,实例的泛型类型必须和引用是一致,在这里 并不存在什么父子关系, 即类型T不能前后赋两个不同值。
2.通配符泛型
在上面的例子中对于当我们声明某一种特定泛型类型的引用时,那么对应的实例的泛型类型就必须和引用的泛型类型一样,这样当我们有多个泛型类型子类实例时,我们就必须声明多个不同的引用,也就是我们的引用被具体化了,换句话说,我们的泛型被具体化了,所以才导致我们的引用也被具体化了。那么如何让一个含有泛型的引用
也可以接受任意的实例类型?
eg: 继续上面的DEMO,在main方法中加入如下声明方式
/**5 * 使用通配符CollectionGenFoo<? extends Collection> * listFoo5这个引用接受所有Collection类型 的实例 * */ CollectionGenFoo<? extends Collection> listFoo5 = null; listFoo5=new CollectionGenFoo<ArrayList>(new ArrayList()); listFoo5=new CollectionGenFoo<LinkedList>(new LinkedList()); listFoo5.getX();//该方法返回值的类型为Collection类型 /** * CollectionGenFoo<?>方式声明引用时 * listFoo5这个引用接受所有Collection类型的实例 * */ CollectionGenFoo<?> listFoo6 = null; listFoo6=new CollectionGenFoo<ArrayList>(new ArrayList()); listFoo6=new CollectionGenFoo<LinkedList>(new LinkedList()); listFoo6.getX();//该方法返回值的类型为Object类型 /* * 下面的报错: * 虽然通配符?可以是任意类型,但是也是有限制的 * 必须是Collection的子类 */ /*报错: *Bound mismatch: The type String is not a valid substitute for the bounded parameter *<T extends Collection> of the type CollectionGenFoo<T> */ //listFoo6=new CollectionGenFoo<String>(new String("test"));
总结:
1. 从5中可以看出当我们使用CollectionGenFoo<? extends SuperClass>的通配符方式声明对象引用时,虽然引用可以接受不 同泛型的对象实例,但是该实例泛型的具体类型已经丢失,全部被上溯成为SuperClass类型
2.从6中可以看出当我们使用CollectionGenFoo<?>的通配符方式声明对象引用时,虽然引用可以接受不 同泛型的对象实例,但是该实例的泛型的具体类型已经丢失,全部被上溯成为Object类型
3.5,6中的 new的实例中的泛型必须是SuperClass的子类或者SuperClass类型。
4.通配符泛型不单可以向下限制,还可以向上限制,如:<? Super ArrayList>,表示类型只能接受ArrayList类型以及其上层父类类型,如:List,Collection
3.泛型方法
未完。。。
泛型在设计的使用场景
发表评论
-
GC日志格式详解(转载)
2012-06-14 10:45 2372原文出处:http://blog.csdn.net/alive ... -
JDK7新增的工具方法列表
2011-07-06 10:46 1467在开源java工具包里,最有名的当属apache com ... -
Apache配置文件(httpd.conf)中文说明(一)
2011-05-04 21:40 1877# #KeepAlive:是否允许稳固的连接(每个连接有多个 ... -
SAR (Service Archive) file in JBoss
2011-03-15 09:54 4160SAR (Service Archive) This tip ... -
分享一个Java_6_JVM参数选项大全
2011-03-13 19:57 730RT,见附件 -
“系统故障诊断”知识全景图
2011-02-28 10:34 868公司同事分享的“系统故障诊断”知识全景图,我觉得很受 ... -
JVM 生产配置
2011-01-09 22:04 1394-server -Xms2g -Xmx2g -XX:PermS ... -
Class学习笔记
2010-05-16 12:31 0要完成的 -
ClassLoader学习之体会
2010-05-16 12:30 0要完成的 -
struts2中获得request response session对象
2010-03-11 15:19 14311、非IoC方式 要获得上述对象,关键Str ... -
JBPM 资料一:基本概念
2010-03-10 08:27 16781. JbpmConfiguration:获取jbpm的相关的 ... -
在Struts2的Action中取得请求参数值的几种方法
2010-01-08 16:45 13450先看GetRequestParameterAction类代码: ... -
Struts2的Action访问Servlet API(转)
2010-01-08 15:44 2070Java代码 public String ... -
OGNL在Struts2中的使用
2010-01-08 11:38 1233OGNL是Object Graph Navigation La ...
相关推荐
Java泛型学习笔记.pdf
java泛型详细学习,深入学习java的不二之选
所谓泛型,就是变量类型的参数化。泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小的抛出ClassCastException的可能。在JDK1.5中,你可以声明一个集合将接收/返回的对象的...
泛型学习笔记2的源代码,泛型 : 要解决类型的安全问题, 如果使用Object类型会带来类型的损失。典型的应用就是在集合中, 集合中理论上可以保存任意对象,实际上我们应该让它泛型化,集合类<元素类型>, 添加元素...
自己总结的java泛型的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合java的爱好者和学习者
基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....
收集的java李兴华老师的课件笔记。感觉还不错,适合回顾和新手补习。
此word学习文档适合泛型入门的人学习,对泛型的介绍内容详细,其中内容均为本人从网上搜集整理。
《Java JDK6学习笔记》是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型...
基于Java的源码-java多线程反射泛型及正则表达式学习笔记和源码.zip
java多线程反射泛型及正则表达式学习笔记和源码.zip
本书是作者近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型、J2SE中标准的API等均进行了...
尚硅谷康师傅java学习笔记。 、2020-4-5 java学习笔记 2020-4-6 java笔记 ---内部类 2020-4-6 java笔记 ---异常 2020-4-6 java笔记 --多线程 2020-4-8 java笔记 String类 2020-4-9 java 比较器 2020-4-10 java笔记 ...
《java jdk 7学习笔记》适合java的初中级读者,以及广大java应用开发人员。 作译者 林信良(网名:良葛格) 学历:台湾大学电机工程学系 经历:台湾升阳教育训练技术顾问、专业讲师,oracle授权训练中心讲师 ...
1.1. JAVA特点 1-4 1.2. 运行原理 1-4 1.3. JAVA目录 1-4 2. 一•基础知识 2-4 2.1. 配置环境 2-4 2.2. Java中基本概念 2-5 3. 二•定义,关键字和类型 3-5 3.1. 注释的三种形式 3-5 3.2. Java代码中的“;”、“{}...
自己整理的JAVA学习笔记,非计算机专业,包括数据基础和泛型编程,集合,多线程,IO流,网络部分未上传,如果觉得对你有帮助就很棒啦!
java代码开发代码优化整理笔记,仅供大家学习交流,如有侵权请尽快联系小编,如有不足,可发表评论,谢谢
详细的描述了java的基本知识,配合看java视频更好了。 笔记中有集合,泛型,线程,的详细案例,还有java.net的资料