Java 泛型:概念、语法和应用

news2024/9/28 11:14:51

文章目录

  • 一、什么是 Java 泛型?
  • 二、为什么要使用泛型
  • 三、Java 泛型的语法
  • 四、Java 泛型的应用
  • 五、Java 泛型的示例
  • 六、总结

随着 Java 编程语言的不断发展和更新,Java 1.5 版本引入了一项全新的特性——Java 泛型(Java Generic),这一特性为 Java 程序员提供了一种更加灵活、安全和通用的编程技术。本文将全面介绍 Java 泛型的概念、语法和应用,并提供一些示例代码来帮助您更好地理解和使用 Java 泛型。

一、什么是 Java 泛型?

Java 泛型(Java Generic)是一种编程技术,它允许程序员在编写 Java 类、接口和方法时定义泛型类型参数,这些类型参数可以在代码中表示不同的类型,使得代码变得更加通用、可重用和类型安全。Java 泛型还提供了运行时类型检查机制,可以在运行时捕获类型错误,从而避免出现类型转换异常等常见问题。

二、为什么要使用泛型

需求:存放学生的成绩

//在集合中使用泛型之前的情况:
    @Test!
    public void test(){
        ArrayList list = new ArrayList();
        list.add(99);
        list.add(98);
        list.add(97); 
        }

存在问题:

问题一:类型不安全

 list.add("Tom");

问题二:强转时,可能出现ClassCastException

for(Object score : list){
            int stuScore = (Integer) score;
            System.out.println(stuScore);
  }

在集合中使用泛型的情况:以ArrayList为例

    @Test
    public void test1(){
       ArrayList<Integer> list =  new ArrayList<Integer>();
        list.add(78);
        list.add(87);
        list.add(99);
        list.add(65);
//        list.add("Tom");
//编译时,就会进行类型检查,保证数据的安全
        for(Integer score : list){        //避免了强转操作
            int stuScore = score;

            System.out.println(stuScore);
        }     
    }

三、Java 泛型的语法

Java 泛型的核心语法包括类型参数、类型变量、类型通配符和上下界限制。

  • 1. 类型参数

Java 泛型定义了一组类型参数,这些类型参数可以在类、接口或方法的声明中使用,以表示可以适用于多种不同类型的代码。类型参数使用尖括号(<>)包裹,并且通常使用单个大写字母表示。例如:

class MyGenericClass<T> {}

上述代码中,类 MyGenericClass 定义了一个泛型类型参数 T,它可以用来表示任何数据类型。

  • 2. 类型变量

类型变量是指在使用泛型类型参数时所定义的具体类型,通常使用小写字母表示。例如:

MyGenericClass<Integer> myGenericInt = new MyGenericClass<Integer>();

上述代码中,我们使用泛型类型参数 T 来定义一个整数类型变量 myGenericInt,并且在实例化类对象时将类型参数 T 替换为具体类型 Integer。

  • 3. 类型通配符
    类型通配符使用问号 ? 表示,表示可以接受任意类型的参数。例如:
List<?> myList;

上述代码中,我们定义了一个泛型列表 List,并使用类型通配符 ? 表示可以接受任何类型的数据。

  • 4. 上下界限制

上下界限制用来限制类型参数的范围,包括上界限制和下界限制。

    1. 上界限制
      上界限制用来限制类型参数的范围,表示类型参数必须是指定类型或指定类型的子类。例如:
class MyGenericClass<T extends Number> {}

上述代码中,我们定义了一个泛型类型参数 T,并使用上界限制 extends Number 表示类型参数必须是 Number 类型或其子类类型。

    1. 下界限制
      下界限制用来限制类型参数的范围,表示类型参数必须是指定类型或指定类型的父类。例如:
void myMethod(List<? super Integer> myList) {}

上述代码中,我们定义了一个方法 myMethod,并使用下界限制 super Integer 表示方法参数必须是 Integer 类型或其父类类型的列表。

四、Java 泛型的应用

Java 泛型可以应用于类、接口、方法等各种代码块中,下面我们将逐一介绍这些用法。

  • 1. 类泛型
    类泛型就是在定义一个类时,在其中定义一个包含泛型类型参数的变量。例如:

java
public class MyGenericClass {
private T element;

public MyGenericClass(T element) {
    this.element = element;
}

public T getElement() {
    return element;
}

public void setElement(T element) {
    this.element = element;
}

}
上述代码中,我们定义了一个泛型类 MyGenericClass,它的类型参数为 T,我们在其中定义了一个变量 element,它的类型为 T,这样就可以用来存储任意类型的数据。

  • 2. 方法泛型

方法泛型就是在方法的声明中使用泛型类型参数。例如:

public class MyGenericMethod {
    public <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element.toString());
        }
    }
}

上述代码中,我们定义了一个泛型方法 printArray,它接受一个泛型数组类型作为参数,使用 for-each 循环遍历数组并打印出每个元素的字符串表示。

  • 3. 接口泛型

接口泛型就是在接口声明中使用泛型类型参数。例如:

public interface MyGenericInterface<T> {
    public T doSomething();
}

上述代码中,我们定义了一个泛型接口 MyGenericInterface,它声明了一个泛型方法 doSomething,返回值类型为 T。

五、Java 泛型的示例

下面我们来看一些 Java 泛型的示例代码,以帮助读者更好地理解和使用 Java 泛型。

  1. 类泛型的示例
public class MyContainer<T> {
    private T element;

    public MyContainer(T element) {
        this.element = element;
    }

    public T getElement() {
        return element;
    }

    public void setElement(T element) {
        this.element = element;
    }

    public static void main(String[] args) {
        MyContainer<Integer> myInt = new MyContainer<>(10);
        MyContainer<String> myString = new MyContainer<>("Hello, World!");
        System.out.println(myInt.getElement());
        System.out.println(myString.getElement());
    }
}

这是一个基于泛型的容器类 MyContainer,它可以存储不同类型的数据,并提供了访问元素和设置元素的方法。通过在类声明中加入一对尖括号 <>,其中的变量 T 表示泛型类型参数,可以使该类变得更加通用和灵活。
在 MyContainer 类的主函数中,我们使用泛型类型参数来创建两个不同类型的实例对象分别存储 Integer 和 String 类型的值,并分别获取元素并输出到控制台。这样,就可以在避免类型转换异常的同时,实现了类型安全和代码复用的效果。

  1. 方法泛型的示例
public class MyGenericMethod {
    public static <T> T pickOne(T a, T b) {
        return Math.random() < 0.5 ? a : b;
    }

    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "World";
        Integer int1 = 10;
        Integer int2 = 20;
        System.out.println(pickOne(str1, str2));
        System.out.println(pickOne(int1, int2));
    }
}

这是一个使用泛型的方法 pickOne,它接受两个相同类型的参数,并以等概率随机返回其中一个参数。在方法声明的 中,T 表示泛型类型参数,使得该方法可以接受任意类型的参数并且不需要进行类型转换。
在类的主函数中,我们分别创建了两个字符串和两个整数对象,并将它们作为参数传递给了 pickOne 方法,然后输出所返回的结果。在输出语句中,也没有指定具体的数据类型,而是由编译器自动推导出了正确的类型。这样,就可以实现代码复用和类型安全的效果。

  1. 接口泛型的示例
public interface MyGenericInterface<T> {
    public T doSomething();
}

public class MyGenericClass implements MyGenericInterface<String> {
    @Override
    public String doSomething() {
        return "Hello, World!";
    }

    public static void main(String[] args) {
        MyGenericClass myGeneric = new MyGenericClass();
        System.out.println(myGeneric.doSomething());
    }
}

这是一个使用泛型接口的示例代码,其中 MyGenericInterface 是一个泛型接口,定义了一个类型参数 T 和一个无参数的方法 doSomething,它返回一个泛型类型 T 的结果对象。
在 MyGenericClass 类中,我们实现了泛型接口 MyGenericInterface,并将泛型类型参数 T 替换为具体类型 String。在 doSomething 方法中,我们返回了一个字符串类型的结果对象 “Hello, World!”。
在类的主函数中,我们创建了一个 MyGenericClass 类的对象,并调用了 doSomething 方法获取它的返回值,并将其输出到控制台。通过使用泛型接口,我们可以灵活地定义和实现不同类型的接口,并保证类型安全和代码复用的效果。

六、总结

总结✌️
泛型的使用 jdk 5.0新增的特性
在集合中使用泛型: 总结:
① 集合接口或集合类在jdk5.0时都修改为带泛型的结构。
② 在实例化集合类时,可以指明具体的泛型类型
③ 指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(比如:方法、构造器、属性等)使用到类的泛型的位置,都指定为实例化的泛型类型。 比如:add(E e) —>实例化以后:add(Integer e)
注意点:泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,拿包装类替换
如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型。

好书分享

在这里插入图片描述

618,清华社 IT BOOK 多得图书活动开始啦!活动时间为 2023 年 6 月 7 日至 6 月 18 日,清华
社为您精选多款高分好书,涵盖了 C++、Java、Python、前端、后端、数据库、算法与机器学习等多
个 IT 开发领域,适合不同层次的读者。全场 5 折,扫码领券更有优惠哦!快来查看详情 !

图书链接:Node.js从基础到项目实践(视频教学版)

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

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

相关文章

Classic AUTOSAR专题 | I/O模块简介

书接上回&#xff0c;上期专题内容中小怿介绍了Classic AUTOSAR之存储模块&#xff0c;相信大家对存储以及NvM已经有了初步的认识了解。接下来我们将继续介绍Classic AUTOSAR专题之I/O模块&#xff0c;同时感兴趣的小伙伴还请持续关注后续内容~ 01 AUTOSAR I/O功能概述 I/O(Inp…

2023年6月DAMA-CDGA/CDGP数据治理工程师认证这里报名

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)【下篇】

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

ZYNQ 7020 开发板开机检测

拿到开发板后检测开发板能否正常工作。 检测需要的工具&#xff1a;电脑、显示器(有HDMI接口)、HDMI线、鼠标、键盘、网线、USB转串口驱动软件。 在检测之前&#xff0c;先要在自己的电脑上安装好终端工具和USB转串口的驱动软件。 终端工具我安装的是 MobaXterm。 USB转串口的驱…

深入理解JavaScript模块化开发

前言&#xff1a; 随着JavaScript应用程序的复杂性不断增加&#xff0c;模块化开发成为了一种必备的技术。通过将代码划分为模块&#xff0c;我们可以提高代码的可维护性、可重用性和可扩展性。在本文中&#xff0c;我们将深入探讨JavaScript模块化开发的概念、优势和不同的模块…

热门自定义报表系统推荐,哪款自定义报表系统更功能更强大?

随着企业管理的日益复杂&#xff0c;越来越多的企业需要一款高效、灵活、易用的自定义报表系统来满足其各种报表制作和数据分析需求。然而&#xff0c;在众多自定义报表系统中&#xff0c;哪款更加强大&#xff1f;今天&#xff0c;我将向大家推荐5款热门自定义报表系统&#x…

设施设备管理系统

凡尔码搭建设施设备管理系统是一种为企业和机构提供维护和管理设备、设施、建筑物和环境等设施的系统。它通过自动化设施的巡检计划、保养计划、通知和维护任务&#xff0c;使设施维护管理的工作更高效率、更科学化&#xff0c;并提高了设施设备的可靠性和使用价值。该系统具有…

asp.net学生考勤管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net学生考勤管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发 asp.net试卷自动生成系统VS开发sq…

谈谈 NLP中 大语言模型 LLM的In-Context Learning(ICL) 能力

In-Context Learning(ICL) 1.介绍 自GPT-3首次提出了In-Context Learning(ICL)的概念而来&#xff0c;ICL目前已经变成了一种经典的LLMs使用方法。 2.思路 ICL主要思路是&#xff0c;给出少量的标注样本&#xff0c;设计任务相关的指令形成提示模板&#xff0c;用于指导待测…

Can We Predict Australian Rainfall?建立LSTM模型预测澳大利亚平均降雨量

数据集&#xff1a;Rain in Australia | Kaggle 数据探索 首先df pd.read_csv(weatherAUS.csv)读入数据&#xff0c;df.shape查看形状为(145460, 23)。 通过df[RainTomorrow].value_counts(dropnaFalse)查看下雨与不下雨标签各自的数量&#xff0c;No为110316&#xff0c;Ye…

初识分类问题

分类问题 根据尺寸把图像分类为纵向图像和横向图像&#xff0c;是二分类问题。 将图像数据转换为坐标&#xff1a; 白色的点是纵向图像&#xff0c;黑色的点是横向图像 若增加更多的图像数据&#xff1a; 分类的目的就是找到这条线&#xff0c;用一条线将图中白色的点和黑色的…

windows 服务程序和桌面程序集成(五)集成为一个EXE

系列文章目录链接&#xff1a; windows 服务程序和桌面程序集成&#xff08;一&#xff09;概念介绍windows 服务程序和桌面程序集成&#xff08;二&#xff09;服务程序windows 服务程序和桌面程序集成&#xff08;三&#xff09;UDP监控工具windows 服务程序和桌面程序集成&…

《Python深度学习基于Pytorch》学习笔记

1.Numpy提供两种基本的对象&#xff1a;ndarray&#xff08;n维数组对象&#xff09;&#xff08;用于储存多维数据&#xff09;和ufunc&#xff08;通用函数对象&#xff0c;用于处理不同的数据&#xff09;。 2.numpy的主要优点&#xff1a;ndarray提供了很多数组化的运算&a…

springboot+vue大学生足球队管理系统 java

(1) 系统管理&#xff1a; 用户分为超级管理员、球队管理员、球队球员、游客&#xff0c;以区分不同用户的操作权限&#xff0c;用户的登录退出。 (2) 前台页面&#xff1a; 1.网站首页&#xff1a;展示系统简介&#xff0c;部分赛事信息&#xff0c;部分院系球队信息&#xff…

号称「碾压」LLaMA的Falcon实测得分仅49.08

作为开源模型界的扛把子&#xff0c;LLaMA 一直备受瞩目。 这是一组由 Meta 开源的大型语言模型&#xff0c;共有 7B、13B、33B、65B 四种版本。其中&#xff0c;LLaMA-13B 在大多数数据集上超过了 GPT-3&#xff08;175B&#xff09;&#xff0c;LLaMA-65B 达到了和 Chinchill…

服务器文件同步机制配置(rsync Sersync)

参考文章链接&#xff1a;http://static.kancloud.cn/curder/linux/78148 在上述参考文章中&#xff0c;对与主从同步部署过程做了详细的操作解释&#xff0c;但对于三台服务器如何互相同步&#xff08;即三个都是master&#xff09;&#xff0c;本文针对三台master相互同步进…

一文读懂redis持久化机制

持久化官网相关参考资料 https://redis.io/docs/manual/persistence/ 持久化就是把redis内存里面保存的数据保存磁盘中&#xff0c;在redis重启或者能够使得数据不会丢失。目前常用的持久化方式有&#xff1a;RDB方式、AOF方式以及RDB AOF两种方式 RDB持久化方式 所谓的RDB…

实现无间断的自动化:Jenkins与GitLab的定时任务工作流程

简介&#xff1a; Jenkins是一个流行的开源自动化服务器&#xff0c;而GitLab是一个强大的代码托管和协作平台。通过结合Jenkins和GitLab&#xff0c;我们可以建立一个强大的定时任务自动化工作流程&#xff0c;实现代码拉取、构建、测试和部署的自动化。本篇博客将介绍如何使…

大屏数据可视化开源项目

一、DataGear —— 数据可视化项目 官网&#xff1a;DataGear - 开源免费的数据可视化分析平台 DataGear 是一款开源免费的数据可视化分析平台&#xff0c;数据可视化看板。 功能特性&#xff1a; 1、多种数据源&#xff0c;支持运行时接入任意提供 JDBC 驱动的数据库&#…