泛型的使用

泛型

泛型的概念

Java泛型是一种在编译时期进行类型检查和类型安全的机制,它可以让我们在编写代码时指定参数或返回值的类型,从而提高代码的可读性和可维护性。

孩童的智商可能还不足以理解泛型的具体概念和实现细节,但是我们可以通过类比的方式来帮助他们理解。

可以将泛型比喻为一个容器,这个容器可以存放不同类型的对象。就像一个玩具箱,可以放入不同种类的玩具,但是每个玩具都有自己的特点和功能。

孩童可以将泛型看作是一个多功能的盒子,可以根据需要放入不同类型的对象。比如,可以有一个盒子专门放玩具车,另一个盒子专门放娃娃。这样,当孩童需要玩具车时,就可以从玩具车盒子中取出玩具车,而不会取出其他类型的玩具。

在Java中,泛型的使用方式类似于上面的例子。我们可以定义一个泛型类或泛型方法,然后在使用时指定具体的类型。这样,编译器会在编译时期进行类型检查,确保我们只能使用指定类型的对象。

例如,我们可以定义一个泛型类Box,用来存放不同类型的对象:

public class Box<T> {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

然后,孩童可以将Box看作是一个玩具箱,可以放入不同类型的玩具:

Box<Car> carBox = new Box<>();
carBox.setItem(new Car());

Box<Doll> dollBox = new Box<>();
dollBox.setItem(new Doll());

在上面的例子中,carBox是一个Box对象,它只能存放Car类型的对象;dollBox是另一个Box对象,它只能存放Doll类型的对象。这样,孩童就可以根据需要选择不同类型的玩具箱,并确保只能取出相应类型的玩具。

通过这种类比的方式,孩童可以初步理解Java泛型的概念和用法,尽管可能还不完全理解其中的技术细节。随着孩童的成长和学习,他们可以逐渐深入理解泛型的原理和更复杂的用法。

泛型的格式

  • <类型>:指定一种类型的格式,这里的类型可以看成是形参

  • <类型1, 类型2……>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参

  • 将来具体调用时,给定的类型可以看成是实参,并且实参的类型只能是引用数据类型

泛型的好处

  • 把运行时期的问题提到了编译期间

  • 避免了强制数据类型转换的问题

泛型类的定义和使用

  • 泛型类的定义格式

    • 格式:修饰符 class 类名<类型>{}

    • 范例:public class Generic<T>{}

      此处 T 可以是任意标识符,常见的有 T、E、K、V 等形式的参数,常用于表示泛型

demo:

创建一个泛型类

package com.itxiaosi.demo01;

/**
 * @Classname : Generic
 * @Description : TODO 泛型类
 * @Author : lin_refuel@qq.com
 */
public class Generic<T> {
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

定义一个学生类

package com.itxiaosi.demo01;

/**
 * @Classname : Student
 * @Description : TODO 学生类
 * @Author : lin_refuel@qq.com
 */
public class Student {
    //学生类的两个基本属性
    private String name; //姓名
    private int age; // 年龄

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试泛型类

package com.itxiaosi.demo01;

/**
 * @Classname : GenericTest
 * @Description : TODO 泛型类测试
 * @Author : lin_refuel@qq.com
 */
public class GenericTest {
    public static void main(String[] args) {
        //TODO 泛型括号里面的类型必须是引用数据类型
        //1.String类型放入
        Generic<String> strG = new Generic<>();
        strG.setT("我是一个字符串");
        String str = strG.getT();
        System.out.println(str); // 我是一个字符串
        System.out.println("====================");
        //2.Integer类型放入
        Generic<Integer> intG = new Generic<>();
        intG.setT(9527);
        Integer interG = intG.getT();
        System.out.println(interG); // 9527
        System.out.println("===================");
        //3.定义的学生类放入
        Generic<Student> StuG = new Generic<>();
        StuG.setT(new Student("小肆",20));
        Student Stud = StuG.getT();
        System.out.println(Stud);
    }
}

运行结果:
在这里插入图片描述

泛型方法

  • 泛型方法的定义格式

    • 格式:修饰符 <类型> 返回值类型 方法名(类型名 变量名){}

    • 范例:public <T> void show(T t)

个人理解泛型方法,可以避免同一个方法多次重载

package com.itxiaosi.demo02;

/**
 * @Classname : Generic
 * @Description : TODO 泛型方法
 * @Author : lin_refuel@qq.com
 */
public class Generic {
    //泛型方法
    public <T> void show(T t){
        System.out.println(t);
    }
}

泛型方法测试

package com.itxiaosi.demo02;

import com.itxiaosi.demo01.Student;

/**
 * @Classname : GenericTest
 * @Description : TODO 泛型方法测试类
 * @Author : lin_refuel@qq.com
 */
public class GenericTest {
    public static void main(String[] args) {
        Generic Gen = new Generic();
        Gen.show("莲");
        Gen.show(1231);
        Gen.show(new Student("小肆",12));
    }
}

运行结果:
在这里插入图片描述

泛型接口

  • 泛型接口的定义格式

    • 格式:修饰符 interface 接口名<类型>{}

    • 范例:public interface Generic<T>{}

demo:
在这里插入图片描述

泛型接口实现类

在这里插入图片描述

泛型接口测试

在这里插入图片描述

运行结果
在这里插入图片描述

泛型通配符

为了表示各种泛型 List 的父类,可以使用类型通配符

  • 类型通配符:<?>

  • List<?> :表示类型未知的 List,它的元素可以匹配 任意类型

  • 这种带通配符的 List 仅表示它是 各种泛型 List 的父类,并不能把元素添加到其中

如果说我们不希望 List<?> 是任何泛型 List 的父类, 只希望他代表某一泛型 List 的父类,可以使用类型通配符的上限

  • 类型通配符上限:<? extends 类型>

  • List<? extends Number> :它表示类型是 Number 或者其子类型

除了可以指定类型通配符的上限,我们还可以指定类型通配符的下限

  • 类型通配符的下限:<? super 类型>

  • List<? super Number> :它表示的类型是 Number 或者其父类型

可以理解为泛型限制符,不能随意写入

package com.itxiaosi.demo04;

import com.itxiaosi.demo01.Student;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname : demo01
 * @Description : TODO 泛型通配符(泛型的限制)
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) {
        //<?> : 尖括号里面的?等同于是 Object ,是所有类的父类,可以随意写入
        List<?> list = new ArrayList<Object>();
        //可以随意放入其他引用数据类型
        List<?> list01 = new ArrayList<Integer>();
        List<?> list02 = new ArrayList<String>();
        List<?> list03 = new ArrayList<Student>();
        //****************************************************
        //<? extends> // 表示继承的上限例如 <? extends Number> 写入泛型只能写入 Number和继承Number的子类
        List<? extends Number> list07 = new ArrayList<Number>();
        List<? extends Number> list04 = new ArrayList<Integer>();
        List<? extends Number> list05 = new ArrayList<Float>();
        List<? extends Number> list06 = new ArrayList<Double>();
        //例如:写入一个没有继承Number的类或者Number的类则是超过上限,出现异常
       // List<? extends Number> list08 = new ArrayList<Object>();
       // List<? extends Number> list08 = new ArrayList<Student>();
       //********************************************************
        //<? super>//表示泛型的下限,例如 <? super Number> 可以写入 Number和Number的父类,不能写入Number的子类
         List<? super Number> list09 = new ArrayList<Object>();
         List<? super Number> list10 = new ArrayList<Number>();
         // Integer是Number的子类,超过了Number的下限,
        // List<? super Number> list11 = new ArrayList<Integer>();
    }
}

可变的参数

可变参数有称为参数个数可变,用作方法的参数出现,那么方法参数的可数就是可变的

  • 格式:修饰符 返回值类型 方法名(数据类型...变量名)

  • 范例:public static int sum(int...a)

注意:

  • 可变参数实际上是一个数组

  • 如果普通参数和可变参数结合使用的话,可变参数需要放到形参列表的最后

demo

package com.itxiaosi.demo05;

/**
 * @Classname : demo01
 * @Description : TODO 可变长的参数
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) {
        // 定义一个两个数相加方法,输出两个数的相加后的值
        System.out.println(Myadd(1,2));
        //TODO 通过可变长参数实现
        System.out.println(Myadd2(1,2,3,4,5,6));
    }

    /**
     *  可变长参数的使用
     * @param a 可变长的参数
     * @return 结果
     */
    private static int Myadd2(int ...a) {
        int sum = 0;
        for(int i : a){
            sum+=i;
        }
        return sum;
    }
    /**
     * 两个数相加
     * @param a 第一个数
     * @param b 第二个数
     * @return 结果
     */
    private static int Myadd(int a, int b) {
        return a+b;
    }
}

可变长参数的使用

所属类方法名说明
Arrayspublic static <T> List <T> asList(T...a)返回由可变长组成的固定大小的列表
Listpublic static <E> List <E> of(E...e)返回包含任意数量元素的不可变列表
Setpublic static <E> Set <E> of(E...e)返回一个包含任意数量元素的不可变集合

list.of和Set.of是jdk9之后才有

demo:

package com.itxiaosi.demo05;

import java.util.Arrays;
import java.util.List;

/**
 * @Classname : demo02
 * @Description : TODO 可变参数的使用
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) {
        // 调用方法 aslist(可变参数)
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 返回的是一个list集合
        System.out.println(list); // 1,2,3,4,5
        // *************************************
        // asList返回的集合是否可以进行 TODO 删除,增加,修改
      //  list.add(6);//不能增加
       // list.remove(2);//不能删除一个值
        list.set(2,1314);// 可以修改里面的值
        System.out.println(list);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unity exe程序置顶和全屏

1.置顶和无边框 设置显示位置和范围 using System; using System.Runtime.InteropServices; using UnityEngine; public class WindowMod : MonoBehaviour {public enum appStyle{FullScreen,WindowedFullScreen,Windowed,WindowedWithoutBorder}public enum zDepth{Normal…

【map】【滑动窗口】【优先队列】LeetCode480滑动窗口中位数

作者推荐 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 本题涉及知识点 滑动窗口 map 优先队列 题目 中位数是有序序列最中间的那个数。如果序列的长度是偶数&#xff0c;则没有最中间的数&#xff1b;此时中位数是最中间的两个数的平均数。 例如&#xf…

「品牌变革必备」品牌战略咨询公司精选策略,引领企业焕新之路

每个成功故事的背后&#xff0c;都有一个强大的品牌战略。每个成功品牌战略的背后&#xff0c;都有品牌战略咨询团队或者公司的支持。那么&#xff0c;如何找到那个能带领您的企业实现突破性成长的战略合作伙伴呢。一起来探究一下。 首先&#xff0c;我们要明确两个定义&#x…

独立站:品牌建设的新高地

一、引言 在当今的商业环境中&#xff0c;品牌建设已成为企业成功的关键因素之一。随着电子商务的迅猛发展&#xff0c;独立站已成为品牌建设的新高地&#xff0c;为企业提供了展示品牌形象、扩大知名度和美誉度的平台。本文将深入探讨独立站在品牌建设中的优势和应用&#xf…

PYTHON基础:线性算法--线性回归|岭回归|套索回归模型

常用的三种线性模型算法–线性回归模型、岭回归模型、套索回归模型 线性模型基本概念 线性模型的一般预测模型是下面这个样子的&#xff0c;一般有多个变量&#xff0c;也可以称为多个特征x1、x2、x3 … 最简单的线性模型就是一条直线直线的方程式&#xff0c;b0是截距&#…

虹科方案丨L2进阶L3,数据采集如何助力自动驾驶

来源&#xff1a;康谋自动驾驶 虹科方案丨L2进阶L3&#xff0c;数据采集如何助力自动驾驶 原文链接&#xff1a;https://mp.weixin.qq.com/s/qhWy11x_-b5VmBt86r4OdQ 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 12月14日&#xff0c;宝马集团宣布&#xff0c;搭载…

Flink1.17实战教程(第四篇:处理函数)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

树莓派安装Nginx搭建web服务器结合内网穿透实现无公网IP远程访问本地站点

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

蓝桥杯嵌入式输入捕获

1.555信号发生器原理图 2.CubeMX相关配置 3.输入捕获测频率和占空比代码

Python 常用模块Logging

Python 常用模块Logging 【序言】 logging模块是专门用来做日志记录的模块 【一】日志等级 默认打印结果到终端上 CRITICAL 50 # 致命错误 ERROR 40 # 错误 WARNING 30 # 警告 INFO 20 # 消息 DEBUG 10 # 调试 NOTSET 0 # 不设置示例&#xff1a; 默认级别为…

Docker自建文件快递柜系统

Docker自建文件快递柜系统。 软件特色&#xff1a; 轻量简洁&#xff1a;FastapiSqlite3Vue2ElementUI 轻松上传&#xff1a;复制粘贴&#xff0c;拖拽选择 多种类型&#xff1a;文本&#xff0c;文件 防止爆破&#xff1a;错误次数限制 防止滥用&#xff1a;IP限制上传次数…

python之Selenium WebDriver安装与使用

首先把python下载安装后&#xff0c;再添加到环境变量中&#xff0c;再打开控制台输入: pip install selenium 正常情况下是安装好的&#xff0c;检查一下“pip show selenium”命令&#xff0c;出现版本号就说明安装好了。 1&#xff1a;如果出现安装错误&#xff1a; 那就用“…

VBA:该工程中的宏被禁止

1、点击文件->选项&#xff0c;选择“信任中心” 2、点击“信任中心设置” 3、点击“宏设置”&#xff0c;选择“启用VBA宏”&#xff0c;点击“确定”

20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850

20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850 2023/12/27 18:40 1、简略步骤&#xff1a; rootrootrootroot-X99-Turbo:~/3TB$ cat Android11.0.tar.bz2.a* > Android11.0.tar.bz2 rootrootrootroot-X99-Turbo:~/3TB$ tar jxvf Androi…

WPF实战项目二十二(客户端):首页添加备忘录与待办事项

1、在View文件夹下新建文件夹Dialog&#xff0c;新建View&#xff1a;AddMemoView、AddToDoView <UserControlx:Class"WPFProject.Views.Dialogs.AddToDoView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://s…

项目接口性能优化方案

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表。会点点Java相关技术栈、帆软报表、低代码平台快速开发。技术尚浅&#xff0c;闭关学习中 &#x1f60…

计算机组成原理——存储器41-60

67、下列有关RAM和ROM得叙述中正确的是(A )。 I RAM是易失性存储器&#xff0c;ROM是非易失性存储器 II RAM和ROM都是采用随机存取方式进行信息访问 III RAM和ROM都可用做Cache IV RAM和ROM都需要进行刷新 A、 仅I和II B、仅I和III C、仅I &#xff0c;II&#xff0c; I…

SparkSQL 执行底层原理解析

从Spark SQL 底层架构可以看到&#xff0c;我们写的SQL语句&#xff0c;经过一个优化器&#xff08;Catalyst&#xff09;处理&#xff0c;转化为可执行的RDD&#xff0c;提交给集群执行。 SQL到RDD中间经过了一个Catalyst&#xff0c;它便是Spark SQL的核心&#xff0c;是针对…

kubeadm开快速的搭建一个k8s集群

kubeadm开快速的搭建一个k8s集群 二进制适合大集群&#xff0c;50台以上主机 kubeadm更适合中小企业的业务集群。 master节点 20.0.0.92 docker kubelet kubeadm kubectl flannel node1 20.0.0. 94 docker kubelet kubeadm kubectl flanne node2 20.0.0.03 docker kubelet…

【Spring Security】认证之案例的使用、MD5加密、CSRF防御

目录 一、引言 1、什么是SpringSecurity认证 2、为什么使用SpringSecurity之认证 3、实现步骤 二、快速实现&#xff08;案例&#xff09; 1、添加依赖 2、配置 3、导入数据表及相关代码 4、创建登录页及首页 5、创建配置Controller 6、用户认证 6.1、用户对象User…