泛型

前言

在没有泛型之前,程序员必须使用Object编写适用于多种类型的代码。很繁琐,也不安全。

泛型的引入使Java有了一个很强的类型系统,允许设计者详细地描述变量和方法的类型要如何变化。

在普通的情况下,实现泛型代码很容易。在更高级的情况下,我们的目标是提供让其他程序员可以轻松使用的类和方法,这对实现者来说会非常复杂。

为什么要使用泛型

用泛型编写的代码可以对多种不同对象的类型进行重用。

没有泛型之前,使用Object(继承)实现不同类型对象间的匹配。这种方法有两个弊端

  • 获取一个值时必须进行强制转换(繁琐)
  • 编译期没有错误检查(不安全)

因此,泛型提供了一种解决方案:类型参数(type parameter)。 使代码更具有可读性。

编译器也可以充分利用这个类型信息。调用get的时候不需要强制转换。编译器还知道add方法有一个类型为String的类型参数,这比Object类型要安全。现在,编译器可以检查,防止你插入错误类型的对象。编译期出现错误比运行期出现类的强制转换异常要好的多。

泛型类

有一个或多个类型变量的类。

例如:定义一个类型变量T,用 <> 括起来,放在类名后边。泛型类还可以有多个类型变量,<T, U>。

变量类型可以应用于方法的返回值类型以及字段和局部变量。

使用具体的类型替换类型变量来实例化反省类型,可以把结果想像成一个普通类。

泛型方法

泛型方法可以定义在普通类中,也可以定义在泛型类中。

注意,泛型变量要放在方法返回值前。

调用泛型方法的方式(例子是调用静态方法):

  • ArrAlg.<String>getMiddle(); 注意调用格式
  • ArrAlg.getMiddle(); 简单调用

类型变量的限定

场景:某个方法参数为泛型T,在方法体中要调用compareTo方法来比较大小,既然使用了泛型,说明该方法可以传入任何参数对象,那么如何知道T所属的类有一个compareTo方法呢?

解决这个问题的方法就是限制T只能是实现了Comparable接口的类。可以通过对变量类型T设置一个限定来实现这一点:public static <T extends Comparable> T min(T[] t)

此时,在调用泛型方法min时只能传递实现了Comparable接口的类型对象的参数。

语法就是:<T extends BoundingType>,T和限定类可以是类也可以是接口。

一个类型变量或通配符可以有多个限定:

  • 类型变量用逗号分隔

    • <T, U extends Comparable>
  • 限定类型用&分隔
    • <T extends Comparable & Serializable>

注意: 可以限定多个接口,类最多只能限定一个。如果有一个类作为限定,这个类必须是第一个限定。

泛型代码和虚拟机

无论何时定义一个泛型,都会自动提供一个原始类型(raw type)。这个原始类型就是去掉类型参数后的泛型类型名。对于无限定的变量替换为Object。

原始类型第一个限定类型来替换类型变量,如果没有给定限定,则替换为Object。例如:

public class Interval<T extends Comparable & Serializable> {
private T lower;
}
// Comparable为第一个限定类型,所以使用它来替换
public class Interval {
private Comparable lower;
}

泛型转换的步骤

  • 对原始方法Pair.getFirst调用返回Object类型
  • 将返回的Object类型转换为Employee类型

泛型转换规则

  • 虚拟机中没有泛型,只有普通的类和方法
  • 所有的类型参数都会替换为他们的限定类型
  • 会合成桥方法来保持多态
  • 为保持类的安全性,必要时会插入强制类型转换

@SuppressWarnings("unchecked")

这个注解会关闭代码检查

泛型的限制与局限性

  • 泛型不能使用基本数据类型
  • 类型比较只适用于原始类型
  • 不能创建泛型数组

通配符

泛型通配符搭配集合使用一般在方法的参数中比较常见

方法中的参数是一个集合,集合如果携带了通配符,要特别注意如下:

1 集合的类型会提升为Object类型。

2 方法中的参数是一个集合,集合如果携带了通配符,那么此集合不能进行添加和修改操作 , 可以删除和获取

在集合中泛型是不支持多态的,如果为了匹配任意类型,我们就会使用泛型通配符了。

<?> 可以表示任意类型

受限通配符

对泛型做约束,给泛型指定类型时,只能是某个类的父类或子类。

  • 下限

    • ? super 类型
  • 上限
    • ? extends 类型

visualgo.net

Java泛型知识总结的更多相关文章

  1. JAVA泛型知识(一)

    Java泛型知识(二)<? extends T>和<? super T> Java1.5泛型指南中文版(Java1.5 Generic Tutorial) 目        录 ...

  2. JAVA泛型知识--> <? extends T>和<? super T>

    <? extends T> 和 <? super T> 是Java泛型中的“通配符(Wildcards)” 和 “边界(Bounds)”的概念 <? extends T& ...

  3. JAVA泛型知识(二)--> <? extends T>和<? super T>

    <? extends T> 和 <? super T> 是Java泛型中的“通配符(Wildcards)” 和 “边界(Bounds)”的概念 <? extends T& ...

  4. Java开发知识之Java中的泛型

    Java开发知识之Java中的泛型 一丶简介什么是泛型. 泛型就是指泛指任何数据类型. 就是把数据类型用泛型替代了. 这样是可以的. 二丶Java中的泛型 Java中,所有类的父类都是Object类. ...

  5. 《Java基础知识》Java 泛型详解

    JDK 1.5 之后,Java 通过泛型解决了容器类型安全这一问题,而几乎所有人接触泛型也是通过Java的容器.那么泛型究竟是什么? 泛型的本质是参数化类型:也就是说,泛型就是将所操作的数据类型作为参 ...

  6. Java核心知识1:泛型机制详解

    1 理解泛型的本质 JDK 1.5开始引入Java泛型(generics)这个特性,该特性提供了编译时类型安全检测机制,允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,即给类型指定一个参 ...

  7. 浅析Java 泛型

    泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...

  8. (翻译)反射处理java泛型

    当我们声明了一个泛型的接口或类,或需要一个子类继承至这个泛型类,而我们又希望利用反射获取这些泛型参数信息.这就是本文将要介绍的ReflectionUtil就是为了解决这类问题的辅助工具类,为java. ...

  9. Java基础知识强化14:Java死亡竞赛题目解析

      一个小型网站上发布了一个称为Java“死亡竞赛”的新项目.测验发布后,超过20000位开发者参加了测验.网站以20道关于Java的多选题为主.我们得到了众多开发者的测验统计数据,今天,我们非常乐意 ...

随机推荐

  1. css盒子模型、垂直外边距合并

    css盒子模型由四部分组成:内容(content).填充(padding).边框(border).边距(margin),其中css样式中定义的width属性是定义内容区域的宽度,正常情况下,设置了内容 ...

  2. 基于express框架的留言板实现步骤

    这个留言板是基于express框架,和ejs模板引擎,首先需要在根目录安装express框架,然后安装ejs模块和body-parser(获取用户表单提交的数据):建立项目目录 message,然后依 ...

  3. Java连接数据库报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

    解决方案 连接Mysql报错 The last packet sent successfully to the server was 0 milliseconds ago. The driver ha ...

  4. spring-aop相关概念

    如果下面有疑问请看完动态代理技术的分析 Aop术语: Target(目标对象):要被增强的方法的对象 Proxy(代理对象):简单的说就是对目标对象进行增强的代理类 Joinpoint(连接点):可以 ...

  5. Java的虚拟线程(协程)特性开启预览阶段,多线程开发的难度将大大降低

    高并发.多线程一直是Java编程中的难点,也是面试题中的要点.Java开发者也一直在尝试使用多线程来解决应用服务器的并发问题.但是多线程并不容易,为此一个新的技术出现了,这就是虚拟线程. 传统多线程的 ...

  6. k8s TLS bootstrap解析-k8s TLS bootstrap流程分析

    当k8s集群开启了TLS认证后,每个节点的kubelet组件都要使用由kube-apiserver的CA签发的有效证书才能与kube-apiserver通信:当节点非常多的时候,为每个节点都单独签署证 ...

  7. Ant Design Pro V5 与 IdentityServer 实现 Password 模式的登录

    最近处于休息状态,想趁着休息时间,为自己做一个后台. 后端框架选用了 Abp.之前公司使用了一些自研的框架,但由于人力资源有限,后期框架的升级及维护都是比较耗时,这次干脆直接使用Abp,即省心又能快速 ...

  8. Fauce:Fast and Accurate Deep Ensembles with Uncertainty for Cardinality Estimation 论文解读(VLDB 2021)

    Fauce:Fast and Accurate Deep Ensembles with Uncertainty for Cardinality Estimation 论文解读(VLDB 2021) 本 ...

  9. vue 实现高德坐标转GPS坐标

    vue 实现高德坐标转GPS坐标 首先介绍一下常见的几种地图的坐标类型: WGS-84:这是一个国际标准,也就是GPS坐标(Google Earth.或者GPS模块采集的都是这个类型). GCJ-02 ...

  10. 【阿里巴巴Java开发手册1.7.0(嵩山版)】编程规约&MySQL 数据库规约

    阿里巴巴Java开发手册1.7.0(嵩山版) 一.编程规约 (一)命名风格 所有命名不得以下划线和$开始和结束. 所有命名不得以拼音或拼音英文混合. 类名使用UpperCamelCase风格. 方法名 ...