三十六、Java 泛型

news2024/11/26 11:48:02

Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是可以使用 Java 泛型

使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。


泛型方法

你可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。

下面是定义泛型方法的规则:

  • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的 <E>)。
  • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
  • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
  • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。

java 中泛型标记符:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  •  - 表示不确定的 java 类型

实例

下面的例子演示了如何使用泛型方法打印不同类型的数组元素:

实例

public class GenericMethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }
 
    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
 
        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组
 
        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组
 
        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}

编译以上代码,运行结果如下所示:

整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O 

有界的类型参数:

可能有时候,你会想限制那些被允许传递到一个类型参数的类型种类范围。例如,一个操作数字的方法可能只希望接受Number或者Number子类的实例。这就是有界类型参数的目的。

要声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界。

实例

下面的例子演示了"extends"如何使用在一般意义上的意思"extends"(类)或者"implements"(接口)。该例子中的泛型方法返回三个可比较对象的最大值。

实例

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

编译以上代码,运行结果如下所示:

3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

泛型类

泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。

和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。

实例

如下实例演示了我们如何定义一个泛型类:

实例

public class Box<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
 
    integerBox.add(new Integer(10));
    stringBox.add(new String("XX教程"));
 
    System.out.printf("整型值为 :%d\n\n", integerBox.get());
    System.out.printf("字符串为 :%s\n", stringBox.get());
  }
}

编译以上代码,运行结果如下所示:

整型值为 :10

字符串为 :XX教程

类型通配符

1、类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是 List<String>,List<Integer> 等所有 List<具体类型实参> 的父类。

实例

import java.util.*;
 
public class GenericTest {
     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        getData(name);
        getData(age);
        getData(number);
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
}

输出结果为:

data :icon
data :18
data :314

解析: 因为 getData() 方法的参数是 List<?> 类型的,所以 name,age,number 都可以作为这个方法的实参,这就是通配符的作用。

2、类型通配符上限通过形如List来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。

实例

import java.util.*;
 
public class GenericTest {
     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        //getUperNumber(name);//1
        getUperNumber(age);//2
        getUperNumber(number);//3
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
   
   public static void getUperNumber(List<? extends Number> data) {
          System.out.println("data :" + data.get(0));
       }
}

输出结果:

data :18
data :314

解析: 在 //1 处会出现错误,因为 getUperNumber() 方法中的参数已经限定了参数泛型上限为 Number,所以泛型为 String 是不在这个范围之内,所以会报错。

3、类型通配符下限通过形如 List<? super Number> 来定义,表示类型只能接受 Number 及其三层父类类型,如 Object 类型的实

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

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

相关文章

火山引擎 DataLeap 的 Data Catalog 系统公有云实践

Data Catalog 通过汇总技术和业务元数据&#xff0c;解决大数据生产者组织梳理数据、数据消费者找数和理解数的业务场景。本篇内容源自于火山引擎大数据研发治理套件 DataLeap 中的 Data Catalog 功能模块的实践&#xff0c;主要介绍 Data Catalog 在公有云部署和发布中遇到挑战…

5. LSTM的C++实现

[C 基于Eigen库实现CRN前向推理] 第三部分&#xff1a;TransposedConv2d实现 &#xff08;含dilation&#xff09; 前言&#xff1a;(Eigen库使用记录)第一部分&#xff1a;WavFile.class (实现读取wav/pcm,实现STFT)第二部分&#xff1a;Conv2d实现第三部分&#xff1a;Tran…

你知道不同U盘在ARM+Linux下的读写速率吗?

优秀的产品离不开完善的测试&#xff0c;即使一个简单的USB接口也要确保稳定性及兼容性。不同的U盘在ARMLinux板卡下的兼容性、速率怎么样呢&#xff1f;本文将为大家提供测试参考数据及详细测试步骤&#xff01; 1. 测试准备 主控选用最近发布的64位Cortex-A55核心板&#xff…

设计模式-day01

1&#xff0c;设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大&#xff08;Christopher Alexand…

深入理解SR-IOV和IO虚拟化

一、背景 SR-IOV&#xff08;Single Root I/O Virtualization&#xff09;是由PCI-SIG组织定义的PCIe规范的扩展规范《Single Root I/O Virtualization and Sharing Specification》&#xff0c;目的是通过提供一种标准规范&#xff0c;为VM&#xff08;虚拟机&#xff09;提供…

springboot+vue职称评审管理系统

开发语言&#xff1a;Java 框架&#xff1a;Springbootssm(SpringSpringMVCMyBatis) JDK版本&#xff1a;JDK1.8 前端框架&#xff1a;vue.js 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/idea都支持 Mave…

前端页面的性能测试

介绍 随着 Web 应用的空前发展&#xff0c;前端业务逐渐复杂&#xff0c;为了处理这些复杂业务&#xff0c;前后端分离&#xff0c;出现了专门应对这种分离架构的应用开发框架&#xff0c;比如 Angular&#xff0c;React&#xff0c;Vue 等&#xff0c;从而也导致 Web 应用的复…

高效率开发Web安全扫描器之路(一)

一、背景 经常看到一些SRC和CNVD上厉害的大佬提交了很多的漏洞&#xff0c;一直好奇它们怎么能挖到这么多漏洞&#xff0c;开始还以为它们不上班除了睡觉就挖漏洞&#xff0c;后来有机会认识了一些大佬&#xff0c;发现它们大部分漏洞其实是通过工具挖掘的&#xff0c;比如说下…

linux服务器监控性能测试

一、服务器实时内存监控 1、top&#xff1a;能够实时监控系统的运行状态&#xff0c;并且可以按照cpu以及内存等进行排序。 输入&#xff1a;top -help就可以出现下面的例子&#xff1a; 命令例子&#xff1a;top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o fiel…

计算机网络——分层结构,协议接口,服务

分层结构 主机进行资源共享时需满足以下条件&#xff1a; &#xff08;1&#xff09;发起通信的计算机要将数据通路进行激活 &#xff08;2&#xff09;告诉网络如何识别主机 &#xff08;3&#xff09;发起通信的主机要查明目的主机是否开机等 &#xff08;4&#xff09;发起…

Java 中你绝对没用过的一个关键字?

这节课给大家介绍一个 Java 中的一个关键字 Record&#xff0c;那 Record 关键字跟不可变类有什么关系呢&#xff1f;看完今天的文章你就知道了。友情提示 Record 关键字在 Java14 过后才支持的&#xff0c;所以是不是被我说中了&#xff0c;还在使用 Java 8 的你一定没用过&am…

vpp hqos分析

vpp支持两套qos实现&#xff0c;一套是基于policer实现的qos&#xff0c;另外一套是基于dpdk的qos套件实现的hqos。 &#xff08;免费订阅,永久学习&#xff09;学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂 更多DPDK相关学习资料有…

DPU网络开发SDK——DPDK(一)

随着软件定义网络SDN的不断发展&#xff0c;网络数据转发面的需求越来越多样化&#xff0c;这体现在更快的数据包处理速率&#xff0c;更高的网络吞吐带宽&#xff0c;更灵活的自定义网络协议。传统的硬件设备无法满足网络协议的自定义&#xff0c;而基于Linux内核网络协议栈的…

故障电弧探测器的必要性及组网方案 安科瑞 时丽花

摘要】&#xff1a;电气设备是建筑中不可缺少的一部分&#xff0c;具有较为重要的作用和意义&#xff0c;在应用过程中不仅能够提升建筑本身实用性能&#xff0c;而且可为消费者提供更加优良的生活环境。但设备一旦在运行过程中出现故障&#xff0c;不仅会影响居民正常生活&…

艾美捷细胞失巢凋亡检测试剂盒测定原理化验方案

对细胞外基质&#xff08;ECM&#xff09;的粘附对于许多粘附细胞的生存和繁殖至关重要细胞。细胞与ECM的粘附丧失或不当粘附导致的细胞凋亡定义为“anoikis”。Anoikis&#xff0c;来自希腊语无家可归的意思&#xff0c;与生理学有关组织更新和细胞稳态的过程。 癌症发展和生长…

做测试8年,33岁前只想追求大厂高薪,今年只求稳定收入

疫情3年&#xff0c;每一个行业的危机&#xff0c;每一个企业的倒下&#xff0c;背后都是无数人的降薪、降职和失业。这也暴露了人生的残酷真相&#xff1a;人活一辈子&#xff0c;总有“丰年”和“荒年” 优秀的测试既过得了丰年&#xff0c;也受得住荒年 一个测试宝妈&…

冒烟测试的7个好处,你是否经常用到它?

以下为作者观点&#xff1a; 冒烟测试(smoke testing)是在开发的早期阶段评估基本的软件组件&#xff0c;以检查它们是否 “着火”&#xff08;有问题&#xff09;&#xff0c;本文旨在介绍冒烟测试及其在程序开发过程中的作用。 什么是冒烟测试&#xff1f; 冒烟测试是在开…

Linux文件权限

Linux文件权限 文件权限介绍 Linux文件权限有三种&#xff1a; 权限对应字符可读(read)r可写(write)w可执行(execute)x 文件权限身份也有三种&#xff1a; 权限身份对应字符文件所有者(user)u文件所有者所在组(group)g其他(other)&#xff0c;即除了文件所有者和其所在组的…

简明误差卡尔曼滤波器(ESKF)及其推导过程

文章目录1. 简明ESKF简介ESKF基本过程及优点ESKF参数含义连续时间上的 ESKF状态方程误差状态方程推导误差状态的旋转项误差状态的速度项完整误差变量的运动学方程离散时间上的ESKF运动学方程ESKF的运动过程ESKF的更新过程ESKF的误差状态后续处理小结1. 简明ESKF 简介 本文主要…

电商新趋势:Starday拿下黑色星期五的制胜法宝是物流速度

国内电商“双十一”购物狂欢季活动已经闭幕&#xff0c;“双十二”又将袭来&#xff0c;但更多人却将眼光放在蓬勃发展的跨境电商行业中。当下跨境电商卖家们正在各大跨境电商服务平台的带领下全力备战&#xff0c;在“黑色星期五”期间推出各类大促活动&#xff0c;奋力冲刺20…