《如何定义一个Java泛型类》

news2024/11/27 14:46:22

《如何定义一个Java泛型类》

      • 1、标题
      • 2、正文
      • 3、代码
        • ①传一个参数的泛型类
        • ②传两个参数的泛型类
        • ③有界限的泛型
        • ④ 定义一个泛型方法
        • ⑤ 泛型界定
        • ⑥ 使用通配符定义一个泛型方法

1、标题

深入理解Java泛型:自定义泛型类的实现方法

2、正文

在Java编程中,泛型是一项非常强大和重要的特性,它可以使我们编写更加通用和灵活的代码。而自定义一个Java泛型类是学习泛型的重要一步,本文将介绍如何自定义一个Java泛型类。

3、代码

①传一个参数的泛型类

定义一个Java输出类,打印构造方法打印的值

public class Print {
    Integer content;
    public Print(Integer content) {
        this.content = content;
    }
    public void print() {
        System.out.println(content);
    }
}

测试类,但是该测试类,只能传入Integer类型,如果想传入字符串类型,引用类型则需要重新定义输出类

public class Test {
    public static void main(String[] args) {
        Print print = new Print(12321);
        print.print();
    }
}

为了使一个输出类可以传入不同的类型进行输出,就要使用到泛型

public class Print<T> {
    T content;
    public Print(T content) {
        this.content = content;
    }
    public void print() {
        System.out.println(content);
    }
}

测试类,通过构造泛型类,则可以传字符串、包装类、引用类型

public class Test {
    public static void main(String[] args) {
        // 传字符串
        Print<String> print1 = new Print<String>("字符串");
        print1.print();
        // 传包装类
        Print<Integer> print2 = new Print<Integer>(12313);
        print2.print();
        // 传引用类型
        Print<User> print3 = new Print<User>(new User("张三"));
        print3.print();
    }
}
②传两个参数的泛型类

有时候需要传两个参数,这两个参数不固定参数类型,则需要定义具备两个参数的泛型类

public class Print<T,K> {
    T content;
    K desc;
    public Print(T content,K desc) {
        this.content = content;
        this.desc=desc;
    }
    public void print() {
        System.out.println("参数值:"+content.toString()+"描述:"+desc.toString());
    }
}

测试,传不同的参数值后输出

public class Test {
    public static void main(String[] args) {
        // 传字符串
        Print<String, String> print1 = new Print<String, String>("字符串", "这是字符串");
        print1.print();
        // 传包装类
        Print<Integer, String> print2 = new Print<Integer, String>(12313, "这是包装类");
        print2.print();
        // 传引用类型,声明User是张三,且年龄是12岁
        Print<User, Integer> print3 = new Print<User, Integer>(new User("张三"), 12);
        print3.print();
    }
}
③有界限的泛型

定义了一个有界限的泛型类,传入的参数必须是Vehicle的子类

public class Print<T extends Vehicle> {
    T content;
    public Print(T content) {
        this.content = content;
    }
    public void print() {
        content.run();
    }
}

测试类,传入Vehicle的子类

public class Test {
    public static void main(String[] args) {
        // User不是Vehicle的子类
//        Print<User> print1 = new Print<User>(new User("张三"));
//        print1.print();
        // 传入Vehicle的子类
        Print<Car> print2 = new Print<Car>(new Car());
        print2.print();
        // 传入Vehicle的子类
        Print<Bus> print3 = new Print<Bus>(new Bus());
        print3.print();
    }
}
④ 定义一个泛型方法

没有对泛型方法进行约束

public class Test {
    public static void main(String[] args) {
        print("字符串");
        print(12312);
        print(new User("张三"));
    }
    public static <T> void print(T content) {
        System.out.println(content.toString());
    }
}

对泛型方法进行约束,传入的不是Vehicle的子类则会报错

public class Test {
    public static void main(String[] args) {
        print("字符串");
        print(12312);
        print(new User("张三"));
        print(new Car());
    }
    public static <T extends Vehicle> void print(T content) {
        System.out.println(content.toString());
    }
}

在这里插入图片描述

⑤ 泛型界定
/**
 * 交通工具的父类
 *
 * @date 2023/11/17
 */
public class Desc {
    void desc() {
        System.out.println("都在路上跑");
    }
}

/**
 * 交通工具的接口类
 *
 * @date 2023/11/17
 */
public interface Vehicle {

    void run();
}

/**
 * 小汽车类
 * @date 2023/11/17
 */
public class Car extends Desc implements Vehicle {

    @Override
    public void run() {
        System.out.println("小汽车");
    }
}

/**
 * 交通工具类
 *
 * @date 2023/11/17
 */
public class Bus extends Desc implements Vehicle {

    @Override
    public void run() {
        System.out.println("公交车");
    }
}

/**
 * 自行车
 *
 * @date 2023/11/17
 */
public class Bike implements Vehicle {
    @Override
    public void run() {
        System.out.println("自行车");
    }
}
public class Test {
    public static void main(String[] args) {
        print(new Car());
        print(new Car());
        print(new Bike());
    }

    /**
     * 限定 T 必须实现 Desc 接口并继承 Vehicle 类
     *
     * @param content
     */
    public static <T extends Desc & Vehicle> void print(T content) {
        System.out.println(content.toString());
    }
}

在这里插入图片描述

⑥ 使用通配符定义一个泛型方法

使用通配符?表示未知类型

public class Test {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("字符串");
        print(list1);

        List<Integer> list2 = new ArrayList<>();
        list2.add(123);
        print(list2);

        List<User> list3 = new ArrayList<>();
        list3.add(new User("张三"));
        print(list3);

    }

    /**
     * 使用通配符?表示位置类型
     *
     * @param content
     */
    public static void print(List<?> content) {
        System.out.println(content.toString());
    }
    
    /**
     * 使用通配符?,限定参数只能是Vehicle的子类
     *
     * @param content
     */
    public static void print(List<? extends Vehicle> content) {
        System.out.println(content.toString());
    }
    
    /**
     * 使用通配符?,限定参数必须是Car本身或者是Car的父类
     *
     * @param content
     */
    public static void print(List<? super Car> content) {
        System.out.println(content.toString());
    }
}

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

openldap-sasl身份认证镜像

背景 在这篇文章中&#xff0c;AD域信息同步至openLDAP我们使用了SASL将身份验证从OpenLDAP委托给AD”这种方案&#xff0c;本文主要来构建此方案的docker镜像。 sasl官网&#xff1a;Cyrus SASL bitnami/openldap镜像地址&#xff1a;containers/Dockerfile bitnami/openl…

ConnectTimeout 和 ConnectionError 的差异

随着网络请求库的不断发展和更新&#xff0c;开发者们在使用不同版本的requests库时&#xff0c;可能会遇到一些差异和问题。 首先&#xff0c;让我们看看问题的具体背景。用户在使用requests库的get方法时&#xff0c;遇到了以下情况&#xff1a; python import requests re…

恭喜顺利结项 | 开源之夏 2023openGauss项目结项结果公示

祝贺&#xff01; 激动人心的时刻终于到来&#xff01;开源之夏 2023 活动结项审核结果正式出炉。此次&#xff0c;openGauss深度参与活动&#xff0c;发布12个openGauss相关项目&#xff0c;10个项目进入开发周期&#xff0c;最终有8个项目成功结项。恭喜所有成功结项的同学&…

【volatality 3】使用说明文档

由于volatility2.6 和3.0 版本之间略有差异,所以特写本文档用来学习参考。 在vol3 中不需要指定profile,而是在命令中指定系统。 如windows.info、Windows.pslist 使用示例 文档说明 本文作者:SwBack 创作时间:‎2022‎年‎6‎月‎14‎日&#xff0c;‏‎15:47:05 知乎:https…

三维模型几何坐标偏差修正(纠正)的常用方法分析

三维模型几何坐标偏差修正&#xff08;纠正&#xff09;的常用方法分析 以下是几个常用的倾斜摄影三维模型几何坐标偏差修正和纠正的方法&#xff1a; 1、基于地面控制点的坐标转换&#xff1a;地面控制点是已知精确地理位置的点&#xff0c;可以通过测量仪器获取其准确的世界…

水厂消毒设施设备还有哪些其他类型?

除了上述提到的紫外线消毒器、臭氧消毒器、氯消毒设备、次氯酸钠消毒设备、过氧化氢消毒器、臭氧水消毒器和电解水制氯设备之外&#xff0c;水厂消毒设施设备还有其他类型&#xff0c;例如&#xff1a; 超声波消毒器&#xff1a;利用超声波的振动和热效应&#xff0c;破坏细菌…

某股份制商业银行:实现高可靠、自动化、可视可控的数据传输

客户简介 国内某股份制商业银行是一家自2000年来在发起设立阶段就引进境外战略投资者的全国性股份制商业银行。自银行成立以来&#xff0c;紧紧抓住多项国家战略实施与金融科技发展带来的时代机遇&#xff0c;已形成业务网络辐射全国、国际化业务蓄势待发、技术产品创新快速迭…

[Vue 代码模板] Vue3 中使用 Tailwind CSS + NutUI 实现侧边工具栏切换主题

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/vzkgy6gvcnpl3u2y 效果示例 配置 src 目录别名 https://www.yuque.com/u27599042/coding_star/ogu2bhefy1fvahfv 配置 Tailwind CSS https://www.yuque.com/u27599042/coding_star/yqzi9olphko9ity1 配置…

如何同步微信通讯录?看这里,学习如何快速添加联系人!

无论是聊天、购物还是支付&#xff0c;微信都扮演着重要的角色。其中&#xff0c;微信通讯录是微信中的一个重要功能&#xff0c;它主要用于管理用户的联系人信息。如何在微信通讯录中快速添加好友&#xff1f;我们可以通过同步手机通讯录来实现。接下来&#xff0c;小编将给大…

万能在线答题考试小程序源码系统 既能刷题 又能考试 带完整的搭建教程

现如今&#xff0c;线上学习和考试已经成为一种趋势。近年来&#xff0c;移动端的普及以及微信小程序的兴起&#xff0c;使得在线答题考试系统变得更加便捷和高效。今天罗峰就来给大家介绍一款万能在线答题考试小程序源码系统&#xff0c;既能刷题&#xff0c;又能考试&#xf…

聊聊ThreadLocal(一)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 话说《中华英雄》有一个…

【文献阅读】Low Cost Edge Sensing for High Quality Demosaicking

[PDF] [Code] 1. 摘要 使用彩色滤光器阵列(CFA)的数码相机需要一个去马赛克程序来形成完整的RGB图像。对于数码相机行业来说&#xff0c;解调速度和解调精度同样重要&#xff0c;因为相机用户已经习惯了即时查看拍摄的照片。此外&#xff0c;与去马赛克相关的成本不应超过使用…

OpenCV入门5——OpenCV的算术与位运算

文章目录 图像的加法运算图像的减法运算图像的乘除运算图像的融合OpenCV位运算-非操作OpenCV位操作-与运算OpenCV位操作-或与异或为图像添加水印 图像的加法运算 # -*- coding: utf-8 -*- import cv2 import numpy as npimg cv2.imread(E://pic//4.jpg)# 图的加法运算就是矩阵…

3ds max 2024 V-Ray 6 ACES workflow 工作流设置

ACES的流程包括2个设置&#xff1a; 1、环境设置&#xff1b;2、贴图设置&#xff1a; 一、环境设置&#xff1a;3ds max 2024已经内置了OCIO文件&#xff1b;设置一下即可&#xff1b; 二、贴图设置&#xff1a; 所有类型贴图加载有默认和加后缀2种方法&#xff1a; 第一…

提高Producer的发送速度

发送一条消息出去要经过三步&#xff0c;一是客户端发送请求到服务器&#xff0c;二是服务器处理该请求&#xff0c;三是服务器向客户端返回应答&#xff0c;一次消息的发送耗时是上述三个步骤的总和。在一些对速度要求高&#xff0c;但是可靠性要求不高的场景下&#xff0c;比…

Python装饰器的用途和实例

说明 装饰器是Python中非常有用的工具&#xff0c;它们可以用于修改或扩展函数或类的行为&#xff0c;而无需修改其原始定义。装饰器通常是一个函数&#xff0c;它接受一个函数作为参数&#xff0c;并返回一个新的函数或类。下面我们将介绍一些常见的装饰器用途和示例。 记录日…

SAP Dump:RFC callback call rejected by positive list

问题描述:配置SM59 连接时报错CALLBACK_REJECTED_BY_WHITELIST 报错简介: RFC callback call rejected by positive list 报错内容: An RFC callback has been prevented due to no corresponding positive list entry being configured. The original RFC called function m…

ceph学习笔记

ceph ceph osd lspoolsrbd ls -p testpool#查看 ceph 集群中有多少个 pool,并且每个 pool 容量及利 用情况 rados dfceph -sceph osd tree ceph dfceph versionsceph osd pool lsceph osd crush rule dumpceph auth print-key client.adminceph orch host lsceph crash lsceph…

vue2、vue3傻傻分不清楚

前端工作也做了几年了&#xff0c;好多东西还是分不清楚。特别是对于最基础的书写格式还是有点模糊不清&#xff0c;今天特地整理一下&#xff0c;以供日后查阅。 vue2 //最纯洁简单的一种创建组件的方式&#xff0c;使用基础 Vue 构造器&#xff0c;创建一个“子类”。 <…

2.认识中台

1.数字化中台初步认识与建设策略 中台的定义 阿里对中台的定义: 中台是一个基础的理念和架构&#xff0c;我们要用中台的思想建设、联通所有基础服务&#xff0c;共同支持上端的业务。业务中台更多的是支持在线业务&#xff0c;数据中台则提供基础数据处理能力和很多的数据产…