Java(7)泛型
一、泛型概述
1、什么是泛型
泛型就是标签,加了泛型,就相当于加了标签,这个容器就只能放这一类物品。
把元素的类型设参数,这个类型参数叫做泛型。
Collection<E>,List<E>,ArrayList<E>这个<E>就是类型参数,即泛型。所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如, 继承或实现这个接口,用这个类型声明变量 、创建对象时)确定(即传入实 际的类型参数,也称为类型实参)。
JDK1.5时引入。
2、为什么用泛型
- 存储时:编译时进行类型检查来保证,存放的都是类型一样的数据,更安全。
- 获取时:获取的都是类型一样的数据,无序强转。
3、在集合中使用泛型
- ① 集合接口或集合类在jdk5.0时都修改为带泛型的结构。
② 在实例化集合类时,可以指明具体的泛型类型。
③ 指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(比如:方法、构造器、属性等)使用到类的泛型的位置,都指定为实例化的泛型类型。
比如:add(E e) --->实例化以后:add(Integer e)。
④ 注意点:泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,拿包装类替换。
⑤ 如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型。
⑥在JDK7中新特性:类型推断
List<String> list = new List<>();后面的泛型可以省略
二、自定义泛型结构
1、泛型类、接口
- 自定义泛型类代码实现:核心思想就是把T当做一个某某类型的参数,只不过需要在尖括号标明
/**
* 自定义泛型类
*/
public class MyGeneric<T> {
String name;
int age;
T decs;//可以把他当做一个类来看,但是并不是类,而是参数
public MyGeneric() {
}
//带参构造器
public MyGeneric(String name, int age, T decs) {
this.name = name;
this.age = age;
this.decs = decs;
}
//get()方法
public T getDecs() {
return decs;
}
//set()方法
public void setDecs(T decs) {
this.decs = decs;
}
//toString()方法
@Override
public String toString() {
return "MyGeneric{" +
"name='" + name + '\'' +
", age=" + age +
", decs=" + decs +
'}';
}
}
- 子类继承父类时,泛型的情况
- 说明:子类是“富二代”,除了指定或保留父类的泛型,还可以增加自己的泛型。
- 情况一:子类不保留父类的泛型
- 父类没有类型,擦除,类型按照Object处理
- 父类是具体类型
- 情况二:子类保留父类的类型
- 全部保留
- 部分保留
- 代码示例
class Father<T1, T2>{
}
//子类不保留父类的泛型
//1)没有类型,擦除--->这时,子类不是泛型
class Son1 extends Father{//等价于class Son extends Father<Object,Object>{
}
//2)具体类型--->这时,子类不是泛型
class son2 extends Father<Integer, String>{
}
//子类保留父类的泛型
//1)全部保留
class Son3<T1, T2> extends Father<T1, T2>{
}
//2)部分保留
class Son4<T2> extends Father<Integer, T2>{
}
//当然子类也可以加上自己的新的泛型类型
注意点
泛型类里的泛型是以参数的形式存在的。
可以有多个参数:
<T1,T2,T3>声明构造器时
- 空参构造器和普通的一样
public MyGeneric() {} - 带参构造器体现在参数上
public MyGeneric(String name, int age, T decs) {
- 空参构造器和普通的一样
泛型不同的引用不能相互赋值
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>(); list1 = list2;//这样是错误的!
泛型如果不指定,就会被擦除,泛型对应的类型按照Object处理,但不等价于Object。
在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态 属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型。(因为,静态方法随着类的加载而加载,而泛型是在实例化的时候指定,晚于静态方法出生)
异常类不能声明为泛型的。
如果想在构造器中初始化一个T类型的数组,要写作:
T[] t = (T[])new Object[capacity]
2、泛型方法
- 理解
- 在方法中出现了泛型的结构,就是泛型方法。
- 泛型方法中的泛型参数与类的泛型参数没有关系。也就是说:泛型方法所属的类是不是泛型无所谓。
- 可以声明为静态的,因为泛型参数是在调用方法时确定的,而不是来加载时。
- 代码实现一个泛型方法
public static <E> List<E> copyFromArrayToList(E[] arr){
//这里的第一个<E>是为了不让编译器把E当做是一个我们自定义的类
ArrayList<E> list = new ArrayList<>();
for(E e : arr){
list.add(e);
}
return list;
}
三、举例泛型类和泛型方法的使用场景
1、泛型类举例:
连接数据库时,操作数据库中的表的记录
DAO类:定义了数据库不同表的一些共性操作的类
public class DAO<T> {}CustomerDAO:定义了专门操作Customer表的类
public class CustomerDAO extends DAO<Customer>{}
2、泛型方法举例
//泛型方法举例
/*
返回的东西是不确定的,比如
需求1:表中有多少条记录
需求2:获取工资最大值
*/
public <E> E getSomething(){
return null;
}
四、泛型在继承上的体现
- 首先,我们知道在多态下,子类的对象可以赋给父类的引用。
- 但是,在泛型情况下,不再存在子父类的关系。
例如,String是Object的子类,但是List<String >并不是List<Object> 的子类。同理在方法参数中也一样适用。这样就导致一个问题,同一功能的方法要重载很多次。 - 区别,类B是类A的子类,那么
B<T>仍然是A<T>的子类。
五、通配符
1、通配符
通配符用 ?来表示,含义为:类A是类B的父类,G<A> G<B>并不存在什么关系,二者的共同父类是:G<?>。这样就不必重载那么多功能相同的方法了。
2、添加通配符后数据的写入何人读出
- 写入:对于List<?>,不能向其中添加数据,只能添加null;
- 读出:可以读取,读取出的数据为Object类型
3、有限制条件的通配符
- 首先,通配符
?可以的范围可以理解为: (无穷小,无穷大) ? extends A的范围就可以理解为:小于等于,即(无穷小,A]? super A的范围就可以理解为:大于等于,即[A,无穷大)
Java(7)泛型的更多相关文章
- [改善Java代码]Java的泛型是类型擦除的
泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型. Java泛型(Generi ...
- Java 中泛型的全面解析(转)
Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在J ...
- Java中泛型 类型擦除
转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类 ...
- Java 泛型 Java使用泛型的意义
Java 泛型 Java使用泛型的意义 @author ixenos 直接意义 在编译时保证类型安全 根本意义 a) 类型安全问题源自可复用性代码的设计,泛型保证了类型安全的复用模板 b) 使用复用性 ...
- 跟着刚哥梳理java知识点——泛型(十三)
一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: public class GenericTest { public static void main(String[] a ...
- 【Java】泛型学习笔记
参考书籍 <Java核心技术:卷1> 泛型, 先睹为快 先通过一个简单的例子说明下Java中泛型的用法: 泛型的基本形式类似于模板, 通过一个类型参数T, 你可以"私人定制&qu ...
- [转] Java 的泛型擦除和运行时泛型信息获取
原文链接 https://my.oschina.net/lifany/blog/875769 前言 现在很多程序员都会在简历中写上精通 Java.但究竟怎样才算是精通 Java 呢?我觉得不仅要熟练掌 ...
- Java 容器 & 泛型:五、HashMap 和 TreeMap的自白
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Java 容器的文章这次应该是最后一篇了:Java 容器 系列. 今天泥瓦匠聊下 Maps. 一.Ma ...
- 【译】9. Java反射——泛型
原文地址:http://tutorials.jenkov.com/java-reflection/generics.html ===================================== ...
- Java“禁止”泛型数组
Java“禁止”泛型数组 原文:https://blog.csdn.net/yi_Afly/article/details/52058708 1. 泛型定义泛型编程是一种通过参数化的方式将数据处理与数 ...
随机推荐
- docker19.03搭建私有容器仓库
一,启动docker后,搜索registry [root@localhost source]# systemctl start docker [root@localhost source]# dock ...
- .net 连接数据库实例
web.config配置 <appSettings> <add key="ConnectionString" value="server=.;datab ...
- 全球首个优秀的华人.net微服务框架 作者:百大僧
话不多说,直接上地址 https://gitee.com/shoubashou/NetCoreMicroService,目标斩获10000star, 通往牛逼的路上,风景差得让人只说脏话. 是全球首个 ...
- 通过代码实现 `OutOfMemory
通过代码实现 OutOfMemory Intro 来尝试写一个发生 OutOfMemoryException 的代码吧,开启煞笔代码第三篇 -- OutofMemory OutOfMemory Out ...
- 那些鼓吹国内首个.NET 5框架的,该醒醒了!
前两天看过园子里有篇[国内首个 .NET 5 框架 XX 斩获 XXX stars,XXX 发布],一顿羡慕嫉妒恨啊.我这.net core 3.1才上手没几天,还没用热乎呢,你这.NET 5的框架都 ...
- Java网关服务-AIO(一)
Java网关-AIO(一) aio:声明一个byteBuffer,异步读,读完了之后回调,相比于Future.get(),可以减少阻塞.减少线程等待,充分利用有限的线程 nio:声明一个byteBuf ...
- 数据恢复软件推荐-easyrecovery绿色破解版(附注册码)免费下载
easyrecovery破解版专注于PC端存储数据的抢救恢复,软件的整体界面风格和360杀毒有些许相似,没有看起来像牛皮藓的杂乱广告,只有六个功能按键,对应你所遇到的数据丢失状况级别,点击最为适合的功 ...
- Redis---03Redis事务
一.Redis事务 1.简述: Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断 2.作用: 主要作用就是串联多 ...
- CodeForces 1408I Bitwise Magic
题意 给定三个整数 \(n,k,c\) 和一个长度为 \(n\) 的序列 \(a\),保证 \(a_i\) 互不相同.可以操作 \(k\) 次,每次随机选择一个 \(a_i\) 变成 \(a_i-1\ ...
- Redis常用命令(6)——SortedSet
ZADD 格式:ZADD key score member [[score member] [score member] ...] 作用:向有序集合key中插入一个或多个元素.如果元素已经存在,更新s ...