Java 基础进阶篇(十)—— 泛型与可变参数

news2024/11/23 15:31:52

文章目录

  • 一、泛型概述
  • 二、泛型的定义
    • 2.1 泛型类
    • 2.2 泛型方法
    • 2.3 泛型接口
  • 三、泛型深入
    • 3.1 泛型通配符
    • 3.2 泛型上下限
    • 3.3 案例:定义一个 “所有车量进行比赛” 的方法
  • 四、可变参数


一、泛型概述

泛型是 JDK5 中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查。

格式:<数据类型>;

好处:统一数据类型。把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能确定下来。

注意:泛型只能支持引用数据类型。集合体系的全部接口和实现类都是支持泛型的使用的。


二、泛型的定义

泛型可以在很多地方进行定义:

  • 类后面 泛型类
  • 方法申明上 泛型方法
  • 接口后面 泛型接口

2.1 泛型类

定义类时同时定义了泛型的类就是泛型类。

格式:修饰符 class 类名<泛型变量> { ... }

作用:编译阶段可以指定数据类型,类似于集合的作用。

在这里插入图片描述
注:此处泛型变量 T 可以随便写为任意标识,常见的如E、T、K、V等。

public class MyArrayList<T> {
    private ArrayList<T> list = new ArrayList<>();
    
    public void add(T t){
        list.add(t);
    }
    public void remove(T t){
        list.remove(t);
    }
}

2.2 泛型方法

定义方法时同时定义了泛型的方法就是泛型方法。

格式:修饰符 <泛型变量> 方法返回值 方法名称(形参列表){...}

作用:方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性。

在这里插入图片描述

public static <T> void printArray(T[] arr){
    if(arr != null){
        StringBuilder builder = new StringBuilder("[");
        for (int i = 0; i < arr.length; i++) {
            builder.append(arr[i]).append(i == arr.length - 1 ? "" : ", ");
        }
        builder.append("]");
        System.out.println(builder);
    }else {
        System.out.println(arr);
    }
}

2.3 泛型接口

使用了泛型定义的接口就是泛型接口。

格式:修饰符 interface 接口名称<泛型变量>{...}

作用:泛型接口可以约束实现类,泛型接口可以让实现类选择当前功能需要操作的数据类型。

在这里插入图片描述

原理:实现类可以在实现接口的时候传入自己操作的数据类型这样重写的方法都将是针对于该类型的操作。

案例:教务系统,提供一个接口可约束一定要完成数据(学生,老师)的增删改查操作。

public interface Data<E> {
    void add(E e);
    void delete(int id);
    void update(E e);
    E queryById(int id);
}
public class Student {
	...
}

public class StudentData implements Data<Student>{
    @Override
    public void add(Student student) {
    }

    @Override
    public void delete(int id) {
    }

    @Override
    public void update(Student student) {
    }

    @Override
    public Student queryById(int id) {
        return null;
    }
}

public class Teacher {
	...
}

public class TeacherData implements Data<Teacher>{
    @Override
    public void add(Teacher teacher) {
    }

    @Override
    public void delete(int id) {
    }

    @Override
    public void update(Teacher teacher) {
    }

    @Override
    public Teacher queryById(int id) {
        return null;
    }
}

三、泛型深入

3.1 泛型通配符

通配符:?,其可以在 使用泛型 的时候代表一切类型。

注:E T K V 是在 定义泛型 的时候使用的。


3.2 泛型上下限

泛型上限:? extends Car,? 必须是 Car 或者其子类。
泛型下限:? super Car,? 必须是 Car 或者其父类。


3.3 案例:定义一个 “所有车量进行比赛” 的方法

需求:定义一个 “所有车进行比赛” 的方法,该方法参数只可接收汽车类型的集合,其中汽车的父类和子类如下:

class Car{
}
class BENZ extends Car{
}
class BMW extends Car{
}

试想 1:如果参数为泛型方式,则任何类的集合都可作为参数,这是错误的。

public static void go(ArrayList<T> cars){

}

试想 2:如果设置参数为父类类型,也是会存在问题:虽然 BMW 和 BENZ 都继承了 Car 但是 ArrayList<BMW>、ArrayList<BENZ>、 ArrayList<Car>没有关系的。

public static void go(ArrayList<Car> cars){

}

因此,可采用“泛型上限” 的方式解决此问题。客户端模拟代码如下:

public class GenericDemo {
    public static void main(String[] args) {
        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        bmws.add(new BMW());
        bmws.add(new BMW());
        go(bmws);

        ArrayList<BENZ> benz = new ArrayList<>();
        benz.add(new BENZ());
        benz.add(new BENZ());
        benz.add(new BENZ());
        go(benz);
    }

    // 所有车比赛
    public static void go(ArrayList<? extends Car> cars){

    }
}

四、可变参数

可变参数用在形参中可以接收多个数据。

格式:数据类型...参数名称

作用:接收参数非常灵活方便。可以不接收参数,可以接收一个或者多个参数,也可以接收一个数组。

可变参数在方法内部本质上就是一个数组

注意:一个形参列表中可变参数只能有一个;可变参数必须放在形参列表的最后面

举例:假如需要定义一个方法求和,求和数字个数不确定。

public static void main(String[] args) {
	System.out.println(getAll()); // 0
	System.out.println(getAll(10)); // 10
	System.out.println(getAll(10, 20, 30)); // 60
	System.out.println(getAll(new int[]{10, 20, 30, 40, 50})); // 150
}

/**
  注意:一个形参列表中只能有一个可变参数,可变参数必须放在形参列表的最后面
  */
public static int getAll(int... nums){
	int co = 0;
	for (int i = 0; i < nums.length; i++) {
		co += nums[i];
	}
	return co;
}

文章参考:Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题)

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

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

相关文章

Linux应用开发:进程间通信 System V

目录 1、查看删除IPC对象 1.1 IPC对象 1.2 ipcs 命令查看系统中的 IPC 对象 1.3 ipcrm 命令删除系统中的 IPC 对象 2、共享内存 2.1 共享内存简介 2.2 共享内存相关API 2.2.1 shmget&#xff1a;创建共享内存 2.2.2 shmat&#xff1a;映射共享内存 2.2.3 shmdt&#…

A40i使用笔记:安装python3.7(素装)

一、前言 项目需求&#xff0c;要用到python3以上&#xff0c;就研究了一下如何安装python&#xff0c;这里也是分享出来安装方法&#xff0c;为各位技术研发人员减少不必要的时间损耗 本文没有安装python其他依赖库&#xff0c;因为我也是在摸索中&#xff0c;所以只限指导到…

「程序员的浪漫」使用 Html、Css、JavaScript 实现 DIY 生日祝福页面 快发给你的朋友吧

前言 从网上搜集整理修改的好用网页生日祝福版本 特点 将三剑客放进一个 Html 文件 点开即用封装好 修改几个参数就可以 DIYDIY 的地方有注释 预览 …省略几张图 源码 有用的话点个 star 不迷路谢谢&#xff01;https://github.com/yangzi0210/Happy-birthday-page

领先的项目协作管理软件OpenProject

本文软件由网友 不长到一百四誓不改名 推荐&#xff1b; 什么是 OpenProject &#xff1f; OpenProject 是一个开源、基于 Web 的项目管理系统&#xff0c;提供了免费的社区版和收费的企业版。OpenProject 拥有完善的文档&#xff0c;API&#xff0c;及丰富的功能&#xff0c;可…

SlickEdit for Windows and Linux crack

SlickEdit for Windows and Linux crack 现在可以在“新建注释”对话框中对颜色进行排序&#xff0c;使调色板中的颜色阵列看起来更符合逻辑。 在拆分或扩展行注释时添加了撤消步骤&#xff0c;这样您只需点击“撤消”一次即可撤消行注释扩展。 已更新VHDL颜色编码&#xff0c;…

【网络】- 计算机网络体系结构 - OSI七层模型、TCP/IP四层(五层)协议

目录 一、概述 二、计算机网络体系结构的形成  &#x1f449;2.1 分层的网络体系结构  &#x1f449;2.2 OSI 参考模型  &#x1f449;2.3 TCP/IP - 事实的国际标准 三、OSI 参考模型 四、TCP/IP 协议 一、概述 但凡学习计算机网络知识&#xff0c;肯定绕不过网络协议的&…

Java 基础进阶篇(八)—— 常用 API

文章目录 一、Object 类二、Objects 工具类三、Math 类四、System 类五、BigDecimal 类 一、Object 类 一个类要么默认继承了 Object 类&#xff0c;要么间接继承了 Object 类&#xff0c;Object 类是 java 中的祖宗类。Object 类的方法是一切子类都可以直接使用的。 因此&…

7.4 电子信息系统预处理中所用放大电路

在电子信息系统中&#xff0c;通过传感器或其它途径所采集的信号往往很小&#xff0c;不能直接进行运算、滤波等处理&#xff0c;必须进行放大。 一、仪表放大器 集成仪表放大器&#xff0c;也称为精密放大器&#xff0c;用于弱信号放大。 1、仪表放大器的特点 在测量系统中…

Binder“一次拷贝“你真懂吗?

前言 谈到到Binder相对于其他传统进程间通信方式的优点的时候&#xff0c;我们总会说Binder只需要做“一次拷贝”就行了&#xff0c;而其他传统方式需要“两次拷贝”。这确实是Binder的优点&#xff0c;但再进一步思考就会碰到两个问题&#xff1a; 这所谓的“一次拷贝”到底…

回溯算法简单介绍

目录 1.回溯算法简单介绍 2.回溯算法框架&#xff1a; 我们用一道题来详细讲解回溯算法的过程 3.全排列问题 1.回溯算法简单介绍 解决一个回溯问题&#xff0c;其实就是一个决策树的遍历过程&#xff0c;我们只需要思考三个问题&#xff1a; 1.路径&#xff1a;就是已经做出…

一起Talk Android吧(第五百四十二回:无进度值ProgressBar)

文章目录 概念介绍使用资源文件实现使用默认设置修改风格使用动画资源 使用代码实现经验总结 各位看官们大家好&#xff0c;上一回中咱们说的例子是"ProgressBar总结",本章回中介绍的例子是" 无进度值ProgressBar"。闲话休提&#xff0c;言归正转&#xf…

linux相关操作

1 系统调用 通过strace直接看程序运行过程中的系统调用情况 其中每一行为一个systemcall &#xff0c;调用write系统调用将内容最终输出。 无论什么编程语言都必须通过系统调用向内核发起请求。 sar查看进程分别在用户模式和内核模式下的运行时间占比情况&#xff0c; ALL显…

MySQL的where表达式中的各种运算符的用法和细节

MySQL的where表达式中的各种运算符的用法和细节 小故事mysql运算符分类where表达式中的运算符between and 和 and运算符的区别in运算符需要注意的点 小故事 今天在研究mysql的where表达式中的运算符的时候&#xff0c;遇到一个有意思的问题。 问题是&#xff1a;以id为主键&am…

玩机搞机----修改手机各项参数工具解析 过验证 变新机

任何的芯片原则上都可以修改当前机型的任何参数。包括但不限于高通 MTk 展讯..... 等其他芯片。众所周知&#xff0c;有的机型 有的版本可以直接修改&#xff0c;有的不行。至于具体原因可以参考我以往的帖子 安卓玩机搞机技巧综合资源-----修复基带 改串码 基带qcn 改相关参数…

三、c++学习(指针引用详解)

上一次直播好像过去很久了&#xff0c;中间有加班&#xff0c;有5 1假期等&#xff0c;现在5 1放假完了&#xff0c;所以继续卷。 C学习&#xff0c;b站直播视频 3.1 指针 这个指针&#xff0c;考虑了很久&#xff0c;一直不知道在哪个地方介绍&#xff0c;为啥纠结&#xf…

Solr(2):Solr的安装

1 安装前的概述 &#xff08;1&#xff09;solr是基于lucene而lucene是java写的&#xff0c;所以solr需要jdk----当前安装的solr-7.5需要jdk-1.8及以上版本&#xff0c;下载安装jdk并设置JAVA_HOME即可。 &#xff08;2&#xff09;下载solr&#xff0c;然后解压即可&#xf…

Map对象的用法(JS)

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;数据结构与算法 &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; 文章目录 MapkeyMap常用语法Map其他语法创建map的其他方式 Map Map是一个键值对形式…

FPGA设计之控制集优化详解

目录 一、前言 二、Control Set控制集 三、Control Set控制集优化 四、优劣 一、前言 在工程设计优化中&#xff0c;综合阶段优化中有一项常见的优化&#xff0c;控制集&#xff08;control set&#xff09;优化&#xff0c;在vivado的Synthesis中有对该配置项的解释&#x…

Android Jetpack组件化之ORM 数据库访问框架详解

一、对象关系映射 - ORM / Object Relational Mapping Android 系统中使用的数据库是 SQLite 关系型数据库 , 使用 Android 提供的 api 访问 SQLite 数据库非常繁琐 , 由此出现了很多 ORM 框架 ; ORM 英文全称 Object Relational Mapping , 对象关系映射 ; 对象关系映射 ORM …

“智能指针:C++中优雅的内存管理解决方案“

前言 欢迎来到&#x1f496;小K&#x1f496;的&#x1f49e;C专栏&#x1f49e;&#xff0c;内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况&#xff0c;这是C和C程序员的噩梦之一。本节将为大家带来解决办法—>智能指针 文章目录 前言1、简介2、为什么…