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. 泛型定义泛型编程是一种通过参数化的方式将数据处理与数 ...
随机推荐
- Helium文档10-WebUI自动化-Text识别网页上的任何文本或标签
前言 Text关键字的作用是识别网页上的文字,在一般UI查找中使用率非常高,但是需要注意,如果网页上有相同的文字,那么只能识别到第一个 入参介绍 以下是Text的源码 有5个如参:后面4个参数是上下左 ...
- Helium文档6-WebUI自动化-S用于通过id\name\classname\xpth定位元素
前言 S方法可以灵活定位元素特别注意,比如to_left_of参数的使用是查找在某个元素左侧的元素,但是默认只会找第一个S方法可以灵活运用,特别是没有id,没有name,只有classname的情况, ...
- CAP-微服务间通信实践
微服务间通信常见的两种方式 由于微服务架构慢慢被更多人使用后,迎面而来的问题是如何做好微服务间通信的方案.我们先分析下目前最常用的两种服务间通信方案. gRPC(rpc远程调用) gRPC-微服务间通 ...
- postMessage 跨域
基于 postMessage 和 localStorage 的跨域本地存储方案 安·记 2014-09-07 2099 阅读 跨域 存储 localStorage HTML5 的 postMessag ...
- 利用transformer进行中文文本分类(数据集是复旦中文语料)
利用TfidfVectorizer进行中文文本分类(数据集是复旦中文语料) 利用RNN进行中文文本分类(数据集是复旦中文语料) 利用CNN进行中文文本分类(数据集是复旦中文语料) 和之前介绍的不同,重 ...
- ipython notesbook 默认路径修改
Windows下,一个很简单的解决小方法! 改目录 前面很多回答已经说了怎么修改目录: 1.cmd: jupyter notebook --generate-config 2.找到 ~\.jupyte ...
- Java学习的第四十二天
1.例4.7弦截法求方程f(x)=x^3-5x^2+16x-80=0的根 import java.util.Scanner; import java.lang.*; public class cjav ...
- SQL Server双机热备之发布、订阅实现实时同步
一.复制的功能概述 SQL Server 复制功能实现了主从库的分离,从而将主库的压力分解掉,主库就主要负责数据的更改等,而主库主要负责查询ji.另外,有了主.从库,则从另一个方面,也了一层安全性,即 ...
- IC晶圆缺货涨价浪潮持续上涨 无线路由芯片WiFi模块受波及严重
正是多事之秋,继受美国贸易战影响后.由于晶圆供不应求,市场各大行业IC纷纷出现了断货,缺货,涨价的现象.这给了本来低迷的经济市场又一重创.WiFi路由芯片的无线路由模块必不可免的受到了波及. 晶圆代工 ...
- 《Clojure编程》笔记 第1章 进入Clojure仙境
目录 背景简述 第1章 进入Clojure仙境 1.1 基础概念 1.2 常用的一些符号 背景简述 本人是一个自学一年Java的小菜鸡,理论上跟大多数新手的水平差不多,但我入职的新公司是要求转Cloj ...