<转载> Java(16):泛型讲解

java泛型反射注解 先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,发现在封装好的方法中,对个别字段的加密满足不了。 解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要获取对应的值 对值进行加密,然后再重新赋值到该对象 立即下载

日期:2017/11/7


1.为什么需要泛型

泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇将立足于代码介绍、总结了关于泛型的知识。

先看下面的代码:

[java]  view plain  copy
  1. List list = new ArrayList();  
  2. list.add("优快云_SEU_Calvin");  
  3. list.add(100);  
  4. for (int i = 0; i < list.size(); i++) {  
  5.   String name = (String) list.get(i); //取出Integer时,运行时出现异常  
  6.   System.out.println("name:" + name);  
  7. }  

本例向list类型集合中加入了一个字符串类型的值和一个Integer类型的值(这样是合法的,因为此时list默认的类型为Object类型)。

在循环中,由于忘记了之前添加了Integer类型的值或其他原因,运行时会出现java.lang.ClassCastException。为了解决这个问题,泛型应运而生。


2.泛型的使用

Java泛型编程是JDK1.5版本后引入的。泛型让编程人员能够使用类型抽象,通常用于集合里面。

只要在上例中将第1行代码改成如下形式,那么就会在编译list.add(100)时报错。

[java]  view plain  copy
  1. List<String> list = new ArrayList<String>();  

通过List<String>,直接限定了list集合中只能含有String类型的元素,从而在上例中的第6行中,无须进行强制类型转换,因为集合能够记住其中元素的类型信息,编译器已经能够确认它是String类型了。


3.泛型只在编译阶段有效

看下面的代码:

[java]  view plain  copy
  1. ArrayList<String> a = new ArrayList<String>();  
  2. ArrayList b = new ArrayList();  
  3. Class c1 = a.getClass();  
  4. Class c2 = b.getClass();  
  5. System.out.println(c1 == c2); //true  

上面程序的输出结果为true。因为所有反射的操作都是在运行时的,既然为true,就证明了编译之后,程序会采取去泛型化的措施。

也就是说Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,成功编译过后的class文件中是不包含任何泛型信息的。


上述结论可通过下面反射的例子来印证:

[java]  view plain  copy
  1. ArrayList<String> a = new ArrayList<String>();  
  2. a.add("优快云_SEU_Calvin");  
  3. Class c = a.getClass();  
  4. try{  
  5.      Method method = c.getMethod("add",Object.class);  
  6.      method.invoke(a,100);  
  7.       
  8. }catch(Exception e){  
  9.     e.printStackTrace();  
  10. }System.out.println(a);  

因为绕过了编译阶段也就绕过了泛型,输出结果为:

[java]  view plain  copy
  1. [优快云_SEU_Calvin, 100]  

4.泛型类和泛型方法

如下,我们看一个泛型类和方法的使用例子,和未使用泛型的使用方法进行了对比,两者输出结果相同,在这里贴出来方便读者体会两者的差异。泛型接口的例子有兴趣可以去找一些资料,这里就不赘述了。


(1)使用泛型的情况

[java]  view plain  copy
  1. public static class FX<T> {  
  2.     private T ob; // 定义泛型成员变量  
  3.   
  4.     public FX(T ob) {  
  5.         this.ob = ob;  
  6.     }  
  7.   
  8.     public T getOb() {  
  9.         return ob;  
  10.     }  
  11.   
  12.     public void showType() {  
  13.         System.out.println("T的实际类型是: " + ob.getClass().getName());  
  14.     }  
  15. }  
  16.     public static void main(String[] args) {  
  17.         FX<Integer> intOb = new FX<Integer>(100);  
  18.         intOb.showType();  
  19.         System.out.println("value= " + intOb.getOb());  
  20.         System.out.println("----------------------------------");  
  21.   
  22.         FX<String> strOb = new FX<String>("优快云_SEU_Calvin");  
  23.         strOb.showType();  
  24.         System.out.println("value= " + strOb.getOb());  
  25. }  


(2)不使用泛型的情况

[java]  view plain  copy
  1. public static class FX {  
  2.     private Object ob; // 定义泛型成员变量  
  3.   
  4.     public FX(Object ob) {  
  5.         this.ob = ob;  
  6.     }  
  7.   
  8.     public Object getOb() {  
  9.         return ob;  
  10.     }  
  11.   
  12.     public void showType() {  
  13.         System.out.println("T的实际类型是: " + ob.getClass().getName());  
  14.     }  
  15. }  
  16.   
  17.     public static void main(String[] args) {  
  18.         FX intOb = new FX(new Integer(100));  
  19.         intOb.showType();  
  20.         System.out.println("value= " + intOb.getOb());  
  21.         System.out.println("----------------------------------");  
  22.   
  23.         FX strOb = new FX("优快云_SEU_Calvin");  
  24.         strOb.showType();  
  25.         System.out.println("value= " + strOb.getOb());  
  26.     }  


两种写法输出结果均为:

[java]  view plain  copy
  1. T的实际类型是: java.lang.Integer  
  2. value= 100  
  3. ----------------------------------  
  4. T的实际类型是: java.lang.String  
  5. value= 优快云_SEU_Calvin  


5.通配符

为了引出通配符的概念,先看如下代码:

[java]  view plain  copy
  1. List<Integer> ex_int= new ArrayList<Integer>();    
  2. List<Number> ex_num = ex_int; //非法的  

上述第2行会出现编译错误,因为Integer虽然是Number的子类,但List<Integer>不是List<Number>的子类。

假定第2行代码没有问题,那么我们可以使用语句ex_num.add(newDouble())在一个List中装入了各种不同类型的子类,这显然是不可以的,因为我们在取出List中的对象时,就分不清楚到底该转型为Integer还是Double了。因此,我们需要一个在逻辑上可以用来同时表示为List<Integer>和List<Number>的父类的一个引用类型,类型通配符应运而生。在本例中表示为List<?>即可。

下面这个例子也说明了这一点,注释已经写的很清楚了。

[java]  view plain  copy
  1. public static void main(String[] args) {  
  2.     FX<Number> ex_num = new FX<Number>(100);  
  3.     FX<Integer> ex_int = new FX<Integer>(200);  
  4.     getData(ex_num);  
  5.     getData(ex_int);//编译错误  
  6. }  
  7.   
  8. public static void getData(FX<Number> temp) { //此行若把Number换为“?”编译通过  
  9.     //do something...  
  10. }  
  11.       
  12. public static class FX<T> {  
  13.     private T ob;   
  14.     public FX(T ob) {  
  15.         this.ob = ob;  
  16.     }  
  17. }  

6.上下边界

看了下面这个上边界的例子就明白了,下界FX<? supers Number>的形式就不做过多赘述了。

[java]  view plain  copy
  1. public static void main(String[] args) {  
  2.     FX<Number> ex_num = new FX<Number>(100);  
  3.     FX<Integer> ex_int = new FX<Integer>(200);  
  4.     getUpperNumberData(ex_num);  
  5.     getUpperNumberData(ex_int);  
  6. }  
  7.   
  8. public static void getUpperNumberData(FX<? extends Number> temp){  
  9.       System.out.println("class type :" + temp.getClass());  
  10. }  
  11.       
  12. public static class FX<T> {  
  13.     private T ob;   
  14.     public FX(T ob) {  
  15.     this.ob = ob;  
  16.     }  
  17. }  

7.泛型的好处

(1)类型安全。 

通过知道泛型定义的变量类型限制,编译器可以更有效地提高Java程序的类型安全。 

(2)消除强制类型转换。 

消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。所有的强制转换都是自动和隐式的。

(3)提高性能。 

[java]  view plain  copy
  1. Lits list1 = new ArrayList();  
  2. list1.add("优快云_SEU_Calvin ");  
  3. String str1 = (String)list1.get(0);  
[java]  view plain  copy
  1. List<String> list2 = new ArrayList<String>();  
  2. list2.add("优快云_SEU_Calvin ");  
  3. String str2 = list2.get(0);  

对于上面的两段程序,由于泛型所有工作都在编译器中完成,javac编译出来的字节码是一样的(只是更能确保类型安全),那么何谈性能提升呢?是因为在泛型的实现中,编译器将强制类型转换插入生成的字节码中,但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来了可能。


8.泛型使用的注意事项

(1)泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

(2)泛型的类型参数可以有多个。

(3)不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错。

[java]  view plain  copy
  1. if(ex_num instanceof FX<Number>){   
  2. }  

(4)不能创建一个确切的泛型类型的数组。下面使用Sun的一篇文档的一个例子来说明这个问题:

[java]  view plain  copy
  1. List<String>[] lsa = new List<String>[10]; // Not really allowed.    
  2. Object o = lsa;    
  3. Object[] oa = (Object[]) o;    
  4. List<Integer> li = new ArrayList<Integer>();    
  5. li.add(new Integer(3));    
  6. oa[1] = li; // Unsound, but passes run time store check    
  7. String s = lsa[1].get(0); // Run-time error: ClassCastException.    

这种情况下,由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList<Integer>而不会出现异常,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。

下面采用通配符的方式是被允许的:

[java]  view plain  copy
  1. List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type.    
  2. Object o = lsa;    
  3. Object[] oa = (Object[]) o;    
  4. List<Integer> li = new ArrayList<Integer>();    
  5. li.add(new Integer(3));    
  6. oa[1] = li; // Correct.    
  7. Integer i = (Integer) lsa[1].get(0); // OK  


9.List与List<?>

(1)List实际上也是List<Object>。List实际上表示持有任何Object类型的原生List。

(2)而List<?>表示具有某种特定类型的非原生List,只是我们不知道那种类型是什么。


原创出处:

http://blog.youkuaiyun.com/seu_calvin/article/details/52230032

Java 泛型详解 Java泛型详解,Java泛型详解,Java泛型详解,Java泛型详解 立即下载

相关推荐

Win10系统下AppScan 10.0.0安装破解全流程(附百度网盘资源)

本文详细介绍了在Windows 10系统上安装和配置AppScan 10.0.0进行Web漏洞扫描的完整流程。内容涵盖环境准备、分步安装、核心文件部署、许可证配置及首次扫描实践,旨在帮助开发人员和安全爱好者快速搭建专业的Web应用安全扫描环境,并提升扫描效率。

u8v9w0x1y的博客 365

Java 中的泛型(两万字超全详解)

博主将用 优快云 记录 Java 后端开发学习之路上的经验,并将自己整理的编程经验和知识分享出来,希望能帮助到有需要的小伙伴。博主也希望和一直在坚持努力学习的小伙伴们共勉!唯有努力钻研,多思考勤动手,方能在编程道路上行至所向。由于博主技术知识有限,博文中难免会有出错的地方,还望各位大佬包涵并批评指正,博主会及时改正;如果本文对小伙伴你有帮助的话,求求给博主一个赞支持一下,可以一起交流,一起加油!!Java泛型详解,史上最全图文详解java 泛型全解 - 绝对最详细Java 泛型,你了解类型擦除吗。

林二月的博客 11万+

华为防火墙 策略路由实现多ISP接入Internet

PC3上网访问Server1时走ISP1。PC4上网访问Server1时走ISP2。1、配置接口IP并加入相应的安全区域。二、ISP2 运营商 R2路由器。一、ISP1 运营商 R1路由器。

一直被模仿,从未被超越 3014

Java泛型详解(史上最全泛型知识详解)

泛型是在JDK5之后引入的一个新特性,可以在编译阶段约束操作的数据类型,并进行检查。泛型的格式为用大白话来说,泛型就好比是给一个标签,通常情况下我们会在开发过程中或者个人学习或练习的过程中使用到泛型;就拿数组的泛型举例来说,我们把数组比作一个药瓶子,我们药瓶子贴上了什么标签,就只能放什么药,如果不管什么药都放在一个药瓶子里,那不得出大事吗?同样容器(数组)写上什么泛型,就只能存放什么数据;这样就不会导致我们存取数据的混乱。这样就解决了我们引言中提到的问题,也就解释了什么是泛型。

m0_70325779的博客 1万+

你的Wi-Fi总断网?可能是DHCP租约到期惹的祸!手把手教你用Windows/路由器设置永久IP或延长租期

本文深入解析家庭Wi-Fi频繁断网的常见原因——DHCP租约到期问题,并提供Windows和路由器设置永久IP或延长租期的详细教程。通过对比静态IP配置与延长租期两种方案,帮助用户有效解决网络不稳定问题,特别适合游戏玩家和远程工作者优化家庭网络环境。

weixin_29305313的博客 1419

一条时间轴上的商品供给:商品供给域事件全景、八大子域事件清单与事件契约规范的工程推演

本文以虚构连锁零售企业“青禾鲜市”为例,用事件风暴重新梳理商品供给域:先剖析同词异义、状态模糊、隐式依赖与被动兜底四类冲突,再以时间轴、八条子域泳道与关键事件铺出全景地图,确立一个事件只有一个户口;随后为总店商品、门店商品、价格、库存、质量、标签、变更通知与操作日志列出聚合、事件、命令与策略,并统一命名、信封结构、版本与幂等规范。程序体检把初稿14个问题清零,仿真显示按聚合版本号更新可售视图可将误判从两位数百分比降到0.019%。文末给出四轮工作坊节奏与新品引入、全国调价、批次召回走查剧本。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 5万+

java 泛型

泛型就是将数据类型参数化,例如我们实现一个存储对象的容器时,并不是直接定义好只能存储一种类型,好的办法就是定义时将类型参数化,也就是泛型,在真实使用时再传入真正的参数,这种参数化类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

Misszhoudandan的博客 2080

2026年中兴微电子数字IC设计笔试题带答案

这篇考试试卷涵盖了数字IC设计的关键知识点,主要包含四个部分:单选题(18分)考查RTL仿真、低功耗设计、跨时钟域处理等基础知识;多选题(15分)涉及低功耗技术、异步FIFO设计和工具链使用;代码设计题(25分)要求实现两级同步器和时钟门控电路;简答题(42分)重点考察异步FIFO原理、ASIC设计流程、FPGA时钟处理和时序违例修复方法。试题注重理论与实践结合,既包含概念性知识也强调实际工程能力,全面检验学生对数字IC前端设计核心技术的掌握程度。

Open 118

Java 中的泛型(超全详解)

泛型的出现就是为了统一集合当中数据类型的尖括号 <> 中的 泛型标识被称作是类型参数,用于指代任何数据类型。T :代表一般的任何类。E :代表 Element 元素的意思,或者 Exception 异常的意思。K :代表 Key 的意思。V :代表 Value 的意思,通常与 K 一起配合使用。S :代表 Subtype 的意思,文章后面部分会讲解示意。自己实现集合/*E: 表示不确定的类型,该类型在类名后面已经定义过了e: 形参的名字,变量名*/

weixin_65752158的博客 3万+

Win10或Win11电脑找不到以太网网络适配器的解决方法

Win10或Win11电脑找不到以太网网络适配器的解决方法

Robot_PLC_HMI_Automation 653

UG\NX二次开发 获取对象的引用集

获取对象的引用集,一个对象可能有多个引用集,下面这个封装函数可以获取对象的所有引用集。

王牌飞行员_里海的博客 489

Java泛型详解

Java泛型机制详解,泛型擦除、泛型数组、泛型方法、泛型上下限、泛型编译期检查

qq_52214750的博客 331

MuJoCo XLA (MJX) 强化学习人形机器人四足机器人入门教程(三)

MJX 是用 JAX 编写的 MuJoCo 实现,可以在 GPU/TPU 上进行大批量训练。在本笔记本中,我们将演示如何使用 MJX 训练 RL 策略。在开始大量 RL 工作负载之前,我们先从一个简单的示例开始!xml = """"""接下来,我们使用 MJX 将 MuJoCo 模型和数据放到 GPU 设备上。下面,我们将打印来自 MuJoCo 和 MJX 的 qpos。

2506_90492529的博客 2472

泛型(Generics Types)学习笔记<一>

Generics Types 泛型学习笔记 1作者:冰云 icecloud(AT)sina.comBLOG: http://icecloud.51.net时间:2004.02.15 版权声明:本文由冰云完成,首发于优快云,作者保留中文版权。未经许可,不得使用于任何商业用途。欢迎转载,但请保持文章及版权声明完整。如需联络请发邮件:icecloud(A

冰云BLOG 4073

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

万字文详解Java泛型

1、泛型的本质是为了参数化类型,也就是在在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型,很明显这种方法提高了代码的复用性。2、泛型的引入提高了安全性,泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。。3、在没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。returnt;*不指定类型泛型擦除。和1。...

youthlql的博客 6210

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java总结篇系列:Java泛型

本文转载自:https://www.cnblogs.com/lwbqqyumidi/p/3837629.html 一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 复制代码 1 public class GenericTest { 2 3 public static void main(String[] args) { 4 List list =...

changqijihua的专栏 317

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java泛型-----转载于百度百科

java泛型 编辑讨论 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。Java语言引入泛型的好处是安全简单。 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类...

坚持住啊 199

【转载】Java泛型(二)

转自:http://www.cnblogs.com/lwbqqyumidi/p/3837629.html 一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(String[] args) { 4 ...

amo1561的博客 89

java获取类的泛型类型

Java获取类的泛型类型 作为一名经验丰富的开发者,你在这篇文章中将教会一位刚入行的小白如何实现“java获取类的泛型类型”。这对于初学者来说可能是一个比较复杂的问题,但通过本文的指导,希望能够帮助他理解并掌握这一领域的知识。 整体流程 在教会小白如何获取类的泛型类型之前,我们首先来看一下整个流程。下面是一个展示步骤的表格...

weixin_27034523的博客 502

Java泛型

泛型类,就是将类型先说明成一个简单的参数,比如T或E(一般就是用T或E),然后通过创建类的对象,并说明对象的参数,比如 1 public class GenericClass <T>{ //定义泛型类,T是类型参数 2 private T obj; 3 4 public T getObj() { 5 return...

bangsi8103的博客 125

java 返回类型为泛型

Java返回类型为泛型 在Java编程中,泛型是一种非常有用的特性,它可以使代码更加灵活且具有通用性。泛型可以让我们编写更加通用的代码,而不需要重复编写相似的代码。在Java中,我们可以定义具有泛型返回类型的方法,这使得方法可以返回不同类型的数据,而不仅仅是固定的一种类型。 什么是泛型? 泛型是Java中的一种特性,它允许...

weixin_40581063的博客 595

java泛型 返回指定类型

给大家整理了一些有关【Java】的项目学习资料(附讲解~~):https://edu.51cto.com/course/35714.htmlJava泛型:返回指定类型 在Java中,泛型是一种强大的特性,它允许我们为类、接口和方法指定类型参数。这使得代码更加灵活、可重用,并且减少了类型转换和类型检查的错误。本文将介绍如何...

weixin_40345119的博客 264

java 泛型约束class

Java 泛型约束 Class 在Java中,泛型是一种强大的特性,它允许我们在编写代码时使用参数化类型,以增强代码的灵活性和安全性。在某些情况下,我们可能想要对泛型进行一些约束,以限制可以传递给泛型的类型。本文将介绍如何在Java中使用泛型约束Class。 什么是泛型约束Class 在Java中,我们可以使用泛型来定义类...

weixin_40583909的博客 167

泛型

1.什么是泛型 JDK5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出) 2.使用泛型应该注意 使用泛型时,泛型类型须为引用类型,不能是基本数据类型 泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入...

weixin_30784141的博客 117

转载------JAVA 泛型

一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(String[] args) { 4 List list =...

chengquying3939的博客 93

java泛型

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

a304096740的博客 91
上一篇: 前端基础(5):html语法(4): <br> <td><tr><label>标签
下一篇: <转载>Java(17):Java常用数据结构及其特征解读
后台技术汇
博客等级 码龄11年 670粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值