Java基础语法<十二> 泛型程序设计
1 意义
泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
常见应用 : ArrayList
2 K T V E ? object等的含义
类型变量使用大写形式
E – Element (在集合中使用,因为集合中存放的是元素)
T – Type(Java 类)(需要时还可以用临近的字母U和S)表示任意类型 S、U、V – 2nd、3rd、4th types
K – Key(键)
V – Value(值)
N – Number(数值类型)
? – 表示不确定的java类型(无限制通配符类型)
Object – 是所有类的根类,任何类的对象都可以设置给该Object引用变量,使用的时候可能需要类型强制转换,但是用使用了泛型T、E等这些标识符后,在实际用之前类型就已经确定了,不需要再进行类型强制转换。
3 泛型方法
public static <T> T getXXX(){
}
类型变量放在修饰符的后面,返回类型的前面
变量类型的限定
<T extends Comparable> T
一个类型变量或通配符可以有多个限定
T extends Comparable & Serializable
限定类型用&分隔,逗号用来分隔类型变量
在Java的继承中,可以根据需要拥有的多个接口超类型,但限定中至多有一个类,如果用一个类作为限定,它必须是限定列表中的第一个。
4 泛型代码和虚拟机
Java中的泛型基本上都是在编译器这个层次来实现的。
在生成的Java字节代码中是不包含泛型中的类型信息的。
使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。 其实编译器通过Code sharing方式为每个泛型类型创建唯一的字节码表示,并且将该泛型类型的实例都映射到这个唯一的字节码表示上。将多种泛型类形实例映射到唯一的字节码表示是通过类型擦除(type erasue)实现的。
无论何时定义一个泛型类型,都自动提供一个相应的原始类型(raw type)。原始类型的名字就是删除类型参数后的泛型类型名。擦除(erased)类型变量,并替换为限定类型(无限定的变量用Object)
4.1 类型擦除
类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。 类型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。
类型擦除的主要过程如下:
1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。
2.移除所有的类型参数。
PS:
1.虚拟机中没有泛型,只有普通类和普通方法,所有泛型类的类型参数在编译时都会被擦除,泛型类并没有自己独有的Class类对象。比如并不存在List<String>.class或是List<Integer>.class,而只有List.class。
2.创建泛型对象时请指明类型,让编译器尽早的做参数检查(Effective Java,第23条:请不要在新代码中使用原生态类型)
3.不要忽略编译器的警告信息,那意味着潜在的ClassCastException等着你。
4.静态变量是被泛型类的所有实例所共享的。对于声明为MyClass<T>的类,访问其中的静态变量的方法仍然是 MyClass.myStaticVar。不管是通过new MyClass<String>还是new MyClass<Integer>创建的对象,都是共享一个静态变量。
5.泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException<String>和MyException<Integer>的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。
5 泛型转换
Java虚拟机中没有泛型,只有普通的类和方法
所有的类型参数都用它们的限定类型替换
桥方法被合成来保持多态
为保持类型安全性,必要时插入强制类型转换
6 约束与局限性
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型
- 不能创建参数化类型的数组
- Varargs警告
- 不能实例化类型变量
- 泛型类的静态上下文中类型变量无效
- 不能抛出或捕获泛型类的实例
- 注意擦除后的冲突
7 通配符类型
7.1 <? extends T>
表示类型的上界,表示参数化类型的可能是T 或是 T的子类
7.2 <? super T >
表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。
7.3 无限定通配符 <?>
ps:
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)
如果既要存又要取,那么就不要使用任何通配符。
Java基础语法<十二> 泛型程序设计的更多相关文章
- java基础语法(二)--单列模式
java基础语法(二)--单列模式 /** * 功能:单列模式 * @author Administrator * */ public class SingletonTest { public sta ...
- 03:Java基础语法(二)
Java基础语法 Java运算符 算术运算符 运算符是一种特殊的符号,用以表示数据的运算.赋值和比较等.1.操作数:参与运算的数据 称为操作数.2.表达式:运算符和操作数的整体 称为表达式.单独的一个 ...
- java基础语法要点<二>(基于1.8)
注解(元数据) 从jdk5 开始,java支持在源文件中嵌入补充信息,称为注释(annotation).注释不会改变程序的动作,也就不会改变程序的语义.但在开发和部署期间,各种工具可以使用这类信息.元 ...
- java基础第十二篇之集合、增强for循环、迭代器和泛型
Collection接口中的常用方法: * 所有的子类子接口都是具有的 * 集合的方法:增删改查 * * public boolean add(E e);//添加元素 返回值表示是否添加成功 * pu ...
- Java基础加强总结(二)——泛型
一.体验泛型 JDK1.5之前的集合类中存在的问题——可以往集合中加入任意类型的对象,例如下面代码: package cn.gacl.generic.summary; import java.util ...
- Java基础(十二):包(package)
一.Java 包(package): 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间.包的作用: 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹 ...
- Java基础之十五 泛型
第十五章 泛型 一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 在面对对象编程语言中,多态算是一种泛化机 ...
- 夯实Java基础(十二)——异常处理
1.异常处理概述 在Java程序执行过程中, 总是会发生不被期望的事件, 阻止程序按照程序员预期正常运行, 这就是Java程序出现的异常. 异常处理是基于面向对象的一种运行错误处理机制,通过对异常问题 ...
- java基础(十二章)
一.变量的作用域(有效的使用范围) 1.变量有2种 1.1成员变量(属性) 声明在类的里面,方法的外面 1.2 局部变量 声明在方法里面或for循环结构中 2.调用时的注意事项(初始值不同.作用域不同 ...
随机推荐
- 论如何把JS踩在脚下 —— JQuery基础及Ajax请求详解
一.什么是JQuery? JQuery是一种JavaScript框架,是一堆大神搞出来的能够让前端程序猿敲更少代码.实现更多功能的工具(在此,跪谢各位JQuery开发大大们!!!).JQuery的使用 ...
- 原生js实现图片网格式渐显、渐隐效果
写正文前先吐槽一下:端午放假完第一天去某千人以上公司面试前端工程师,第一轮是我应聘职位的部门小领导,谈的不错,面试主要围绕要用到的技术来:第二轮来了我要说的正主,我了个去,问的问题一个和前端无关,问我 ...
- 搭建免费wifi,嗅探接入该wifi的所有网络信息
环境: 1: create_ap , 搭建免费wifi. 2: wireshark , 嗅探网络信息. 搭建热点 搭建热点: git clone https://github.com/oblique/ ...
- Mavnen的几种依赖关系
学习mavnen的时候有几种依赖关系 首先,说一下maven的依赖关系用来干什么? 就是用来控制编译.测试.运行三种classpath的关系 1.compile 的范围 当依赖的scope为compi ...
- Android布局方式
1. LinearLayout(线性布局) android:orientation="vertical" android:layout_width="wra ...
- java之真假分页
真分页(要的是什么范围的记录在数据库查的时候就只查这几条记录):select s.* from (select *,row_number() over(order by SLoginId) as ro ...
- Shiro眼皮下玩ajax,玩出302 Found(实践得经验)
2017/06/14这一天,是我玩Shiro安全框架最刻骨铭心的一天.因为Shiro今天给我深深的补了一刀,在这儿我也给各位补一刀吧,其实问题很简单,解决方式也极其简单,只是给各位分享一下这个错误,纯 ...
- Javascript 严格模式use strict
一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:“严格模式”(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. 设立”严格模式”的目 ...
- 就是要你懂Java中volatile关键字实现原理
原文地址http://www.cnblogs.com/xrq730/p/7048693.html,转载请注明出处,谢谢 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是j ...
- golang 私钥"加密"公钥"解密"
---恢复内容开始--- 之前工作主要使用C/C++与银行/第三方支付对接,但C/C++无法满足客户"当天给协议明天实盘上载"的开发速度以及现公司一些特殊情况,所以决定用go来 ...