泛型的小结

news2024/11/28 3:30:22

文章目录

    • 什么是泛型
      • 泛型的相关概念
      • 泛型的作用
    • 泛型的使用
      • 泛型类语法
      • 泛型接口语法
      • 泛型方法语法
      • 泛型类的简单示例
      • 泛型接口的简单示例
      • 基于泛型的简单工厂方法
      • 泛型的上界与下界
    • 泛型的一些使用建议

什么是泛型

从JDK1.5开始引入泛型(generic)语法。对类型实现了参数化,编辑器根据上下文推导出实参类型,省略了实参类型的填写。

泛型的相关概念

术语准备

术语范例说明
参数化的类型List<String>表示List中元素的类型为String的容器
实际类型参数String泛型使用时的实参
泛型List<E>声明中具有一个或者多个类型参数的类或接口即泛型
形式类型参数E泛型声明中的形参
原生态类型ListRaw Type。即没有使用泛型,主要是为了兼容之前大量没有使用泛型的代码。
有限制类型参数<E extends Number>只接受 Number 的子类型或者 Number 本身作为 E 的类型实参。 范围上界
递归类型限制<T extends Comparable<T>>只接收实现了Comparable接口的。范围上界
有限制通配符类型List<? extends Number>只接受Number 或其子类类型。范围上界
无限制通配符类型List<?>可以接收任意类型
类型令牌String.class类的字面用在方法传递时的称呼
泛型方法static <E> List<E> aslist(E[] a)

泛型的编译时进行泛型擦除

在这里插入图片描述

程序编写的时候可以指定了泛型的元素类型为String类型,在编译的时候就变成Object。

擦除机制,在编译的过程中,将泛型转换(所有类型)为Object的机制。

泛型的作用

  • 加强类型安全检查:存放元素时,指明容器接收的对象的类型,让编译器进行类型安全检查
  • 无需手动进行类型转换,加快运行效率:取出元素时,无需手动进行类型转换,加快运行效率

在这里插入图片描述

进行类型安全检查之后,会在编译过程中反馈错误,减少运行时的错误。

泛型的使用

泛型常用的形参大写字母

  • E 表示 Element
  • K 表示 Key
  • V 表示 Value
  • N 表示 Number
  • T 表示 Type
  • S, U, V - 第二、第三、第四个类型

泛型类语法

class 类名称 <泛型标识、泛型标识,...> {
    private 泛型标识 变量名;
    ......
}

泛型接口语法

interface 接口名称 <泛型标识,泛型标识,...>{
        泛型标识 方法名();
}      

泛型方法语法

方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表){

}

泛型类的简单示例

// 定义泛型类
public class GenericClass<T, N> {
    private T value1;
    private N value2;

    // 使用泛型类型作为形参类型和返回值
    public T getValue1() {
        return value1;
    }

    public void setValue1(T value1) {
        this.value1 = value1;
    }

    public N getValue2() {
        return value2;
    }

    public void setValue2(N value2) {
        this.value2 = value2;
    }

    public static void main(String[] args) {
        GenericClass<Integer, String> s1 = new GenericClass<>();
        s1.setValue1(1);
        s1.setValue2("XX");
        System.out.println(s1.getValue1() + ":" + s1.getValue2());
        GenericClass<Double, String> s2 = new GenericClass<>();
        s2.setValue1(1.1);
        s2.setValue2("YY");
        System.out.println(s2.getValue1() + ":" + s2.getValue2());
    }
}

泛型接口的简单示例

在接口中定义的类型参数可以在接口中当做类型使用,任何需要类型的地方都可以使用类型参数替代

// 定义泛型接口的类型参数为T
public interface Humans<T> {
    // 使用类型参数T作为方法参数类型
    void say(T t);
	// 使用类型参数T作为返回值类型
    T get();
}

// 实现泛型接口的时候传入类型
public class BlackHuman implements Humans<BlackHuman> {
    public final String name;

    public BlackHuman(String name) {
        this.name = name;
    }

    @Override
    public void say(BlackHuman yellowHuman) {
        System.out.println("我叫" + this.name + ",是黑种人");
    }

    @Override
    public BlackHuman get() {
        return this;
    }
}

public class Demo {

    public static void main(String[] args) {
        BlackHuman blackHuman = new BlackHuman("乔丹");
        blackHuman.say(blackHuman);
        System.out.println(blackHuman.get().name);
    }
}

基于泛型的简单工厂方法

public interface IService {
    String getServiceName();
}
public class MyService1 implements IService {
    @Override
    public String getServiceName() {
        return "My Service1.";
    }
}
public class MyService2 implements IService {
    @Override
    public String getServiceName() {
        return "My Service2.";
    }
}
package com.donny.demo;

/**
 * @author 1792998761@qq.com
 * @description
 * @date 2023/10/8
 */
public class ServiceFactory {

    private ServiceFactory() {
    }

    // 简单写法-通过额外参数表名服务
    public static IService getService(String key) {
        if ("MyService1".equals(key)) {
            return new MyService1();
        } else if ("MyService2".equals(key)) {
            return new MyService2();
        } else {
            return null;
        }
    }

    // 使用泛型方法
    public static <T> T getInstance(Class<T> className) {
        T result = null;
        try {
            result = className.newInstance();
        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
        return result;
    }
}
public class Demo {

    public static void main(String[] args) {
        IService service1 = ServiceFactory.getInstance(MyService1.class);
        IService service2 = ServiceFactory.getInstance(MyService2.class);
        System.out.println(service1.getServiceName());
        System.out.println(service2.getServiceName());
    }
}

泛型的上界与下界

由于java中继承的特性

上界语法

class 类名称 <类型标识 extends 类型边界> {
    ......
}

类型边界可以是类,也可以是接口。若类型边界是类,那么泛型中的类型只能接受边界类本身或其子类。若类型边界是接口,那么泛型中的类型必须实现了边界接口

// 传入的类型需要是Number或Number的子类
public interface Price<? extends Number> {
}

// 传入的类型需要实现Comparable接口
public class ApplicableTransition<? extends Comparable<E>> {
}

下界语法

class 类名称 <类型标识 super 类型边界> {
    ......
}

类型边界可以是类,也可以是接口。若类型边界是类,那么泛型中的类型只能接受边界类本身或其父类

泛型的一些使用建议

  1. 不使用原生态类型

  2. 消除非受检警告

    可以在类,方法,对象声明上增加注解来消除非受检个告警

    @SuppressWarnings("unchecked")
    
  3. 使用泛型时,列表优先于数组

  4. 利用有限通配符提升api的灵活性

  5. 优先考虑类型安全的异构容器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

北邮22级信通院数电:Verilog-FPGA(4)第四第五周实验 密码保险箱的设计

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.密码箱的功能和安全性 显示&#xff1a;…

Python—Scrapy实践项目

爬取豆瓣电影2022年Top250部经典电影 1.项目概述 从https://movie.douban/top250爬取电影的标题、评分、主题。我在之前使用普通的爬虫实现了类似的功能&#xff0c;可以对比来进行学习&#xff08;Python爬虫——爬虫基础模块和类库&#xff08;附实践项目&#xff09;&#…

Spring框架(中)

1、基于注解管理Bean&#xff1a; 1、开启组件扫描&#xff1a; Spring 默认不使用注解装配 Bean&#xff0c;因此我们需要在 Spring 的 XML 配置中&#xff0c;通过 context:component-scan 元素开启 Spring Beans的自动扫描功能。开启此功能后&#xff0c;Spring 会自动从扫…

JVM CMS和G1执行过程比较

CMS CMS&#xff08;Concurrent Mark Sweep&#xff09;收集器是一种以获取最短回收停顿时间为目标的收集器。由于大部分 Java 应用主要集中在互联网网站以及基于浏览器的 B/S 系统的服务端&#xff0c;这类应用通常会较为关注服务的响应速度&#xff0c;希望系统的停顿时间尽…

公司软文怎么写?如何写好软文?

软文&#xff0c;即柔性广告&#xff0c;是通过文字、图片等形式&#xff0c;以一种隐性的方式&#xff0c;将广告信息融入到文章中&#xff0c;以达到宣传、推广的目的。它相较于硬广告&#xff0c;更能深入人心&#xff0c;更易被接受。 首先&#xff0c;软文能够提升品牌的…

xlsx使用table_to_book报错Uncaught Unsupported origin when DIV is not a TABLE

背景&#xff1a;const workbook XLSX.utils.table_to_book(document.querySelector(‘#table-export’),{ raw: true//保留原始字符串 })报错Uncaught Unsupported origin when DIV is not a TABLE 原因&#xff1a;el-table是div格式 过程1&#xff1a;获取深层次的table…

使用Docker安装JupyterHub

安装JupyterHub 拉取Jupyter镜像并运行容器 docker run -d -p 8000:8000 --name jupyterhub jupyterhub/jupyterhub jupyterhub # -d&#xff1a;后台运行 # -p 8000:8000&#xff1a;宿主机的8000端口映射容器中的8000端口 # --name jupyterhub&#xff1a;给运行的容器起名…

H3C 防火墙策略

H3C防火墙有安全策略和域间策略&#xff0c;安全策略的优先级大于域间策略&#xff0c;会优先匹配安全策略&#xff0c;匹配不到才会匹配域间策略 域间策略&#xff1a;any to any的域间策略优先级低于具体的区域到具体的区域的域间策略 安全策略匹配顺序&#xff1a;从上到下…

剑指offer——JZ34 二叉树中和为某一值的路径(二) 解题思路与具体代码【C++】

一、题目描述与要求 二叉树中和为某一值的路径(二)_牛客题霸_牛客网 (nowcoder.com) 题目描述 输入一颗二叉树的根节点root和一个整数expectNumber&#xff0c;找出二叉树中结点值的和为expectNumber的所有路径。 1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过…

第 366 场周赛 LeetCode 周赛题解

A 分类求和并作差 模拟 class Solution { public:int differenceOfSums(int n, int m) {int res 0;for (int i 1; i < n; i)res i % m ! 0 ? i : -i;return res;} };B 最小处理时间 排序&#xff1a;设四个 p r o c e s s o r T i m e processorTime processorTime 的元…

【LeetCode 算法专题突破】二分查找(⭐)

文章目录 前言1. 二分经典模板题目题目描述代码&#xff1a; 2. 在排序数组中查找元素的第一个和最后一个位置题目描述代码 3. 有效的完全平方数题目描述代码 4. 寻找峰值题目描述代码 5. 寻找旋转排序数组中的最小值题目描述代码 6. 点名题目描述代码 总结 前言 我刷过不少算…

java: 警告: 源发行版 17 需要目标发行版 17

一、遇到问题&#xff1a; java: 警告: 源发行版 17 需要目标发行版 17 二、分析原因&#xff1a;JDK版本不一致 在idea中编辑器中修改JDK配置 三、解决问题 找到settings -- Build,Execution,Deployment -- compiler -- JavaCompiler 进行更改版本 另外还要找到两个地方的J…

科普②| 大数据有什么用?大数据技术的应用领域有哪些?

1、提供个性服务很多人觉得大数据好像离我们很远&#xff0c;其实我们在日常所使用的智能设备&#xff0c;就需要大数据的帮助。比如说我们运动时候戴的运动手表或者是运动手环&#xff0c;就可以在我们平时运动的时候&#xff0c;帮助我们采集运动数据及热量消耗情况。进入睡眠…

类目体系设计总结

一、背景 公司窗帘产品在做分类调整&#xff0c;从原先二级类目调整为三级类目&#xff0c;相对于平台电商我们的类目层次结构要简单很多&#xff08;没有定义商品动态属性等&#xff09;&#xff0c;但对于也有上万款SKU的系统来讲,做好基础的分类对于采购、商品促销、数据报…

消息称三星智能戒指 Galaxy Ring 将延期发布

三星和苹果旗下的智能戒指早有传闻&#xff0c;而最近根据外媒The Elec 报道&#xff0c;三星的智能戒指可能被延期至 2024 年第三季度后发布&#xff0c;这款名为 Galaxy Ring 的智能戒指主要面向健康和 XR 头显市场&#xff0c;可以比 Galaxy Watch 提供更准确的身体及健康数…

Flutter_Slider_SliderTheme_滑杆/滑块_渐变色

调用示例以及效果 SliderTheme(data: SliderTheme.of(context).copyWith(trackHeight: 3,// 滑杆trackShape: const GradientRectSliderTrackShape(radius: 1.5),// 滑块thumbShape: const GradientSliderComponentShape(rectWH: 14, overlayRectSpace: 4, overlayColor: Colou…

网络模型之OSI七层网络模型、TCP/IP四层网络模型

一、计算机网络是什么&#xff1f; 计算机网络是指由通讯网络相互连接的许多自主工作的计算机构成的集合体。 二、网络模型是干什么的&#xff1f; 网络模型就是研究计算机网络中各个部件是以何种规则进行通行。 三、OSI七层网络模型 OSI 是 Open System Interconnection 的…

【Amazon】基于AWS云实例(CentOS 7.9系统)使用kubeadm方式搭建部署Kubernetes集群1.25.4版本

文章目录 前言实验架构介绍K8S集群部署方式说明使用CloudFormation部署EC2实例集群环境准备修改主机名并配置域名解析&#xff08;ALL节点&#xff09;禁用防火墙禁用SELinux加载br_netfilter模块安装ipvs安装 ipset 软件包同步服务器时间关闭swap分区安装Containerd 初始化集群…

40V汽车级P沟道MOSFET SQ4401EY-T1_GE3 工作原理、特性参数、封装形式—节省PCB空间,更可靠

AEC-Q101车规认证是一种基于失效机制的分立半导体应用测试认证规范。它是为了确保在汽车领域使用的分立半导体器件能够在严苛的环境条件下正常运行和长期可靠性而制定的。AEC-Q101认证包括一系列的失效机制和应力测试&#xff0c;以验证器件在高温、湿度、振动等恶劣条件下的可…

97 # session

koa 里的 cookie 用法 koa 里内置了设置 cookie 的方法 npm init -y npm i koa koa/router用法&#xff1a; const Koa require("koa"); const Router require("koa/router"); const crypto require("crypto");const app new Koa(); let …