Java 泛型机制详解

news/2025/1/11 21:42:44/

tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。

推荐:体系化学习Java(Java面试专题)

文章目录

  • 一、Java 中为什么会引入泛型?
  • 二、泛型的应用
  • 三、泛型接口
  • 四、泛型方法
  • 五、泛型的上下限

一、Java 中为什么会引入泛型?

Java 引入泛型的主要目的是为了提高代码的类型安全性和可读性。在 Java 5 之前,集合框架中的容器可以存储任意类型的对象,这就使得程序员需要在运行时进行类型转换,容易引发类型转换异常。而引入泛型后,集合框架中的容器可以限定存储的元素类型,使得程序员可以在编译时进行类型检查,避免了类型转换异常的发生。此外,泛型还可以提高代码的可读性和可维护性,使得代码更易于理解和修改。泛型的引入使得 Java 语言更加类型安全,更加适合大规模软件开发。

接下来我们举个例子说明为什么:
假设有一个需求,需要编写一个方法,用于比较两个对象是否相等。最初的实现可能是这样的。

public static boolean compareObject(String s1, String s2) {return s1.equals(s2);
}

但是入参不一定是 String,也有可能是 int、long 等,那么该怎么写呢?难道每个都写一遍?

public static boolean compareObject(String s1, String s2) {return s1.equals(s2);
}public static boolean compareObject(Integer s1, Integer s2) {return s1.equals(s2);
}

这样的代码可读性,可维护性都很差,于是我们用泛型进行改进, 一个方法就搞定了。

public static <T> boolean compareObjects(T o1, T o2) {return o1.equals(o2);
}

二、泛型的应用

泛型是 Java 中的一个重要特性,它可以让我们编写更加通用、可复用的代码。

package com.pany.camp.base;public class Genericity<T, U> {private T first;private U second;public Genericity(T first, U second) {this.first = first;this.second = second;}public T getFirst() {return first;}public U getSecond() {return second;}public void setFirst(T first) {this.first = first;}public void setSecond(U second) {this.second = second;}@Overridepublic String toString() {return "(" + first + ", " + second + ")";}
}

这个示例中定义了一个泛型类 Genericity,它有两个类型参数 T 和 U,分别表示 Genericity 中的两个元素的类型。Genericity类有一个构造函数,用于初始化 Genericity对象的两个元素。Genericity 类还有一些方法,用于获取和设置 Genericity 对象的元素,以及将 Genericity 对象转换成字符串表示。

package com.pany.camp.base;public class GenericityMain {public static void main(String[] args) {Genericity<String, Integer> pair = new Genericity<>("Hello", 123);// 输出:(Hello, 123)System.out.println(pair);}
}

在这里插入图片描述

它的第一个元素是一个字符串,第二个元素是一个整数。使用泛型可以让我们编写更加通用、可复用的代码,可以在不同的场景中使用相同的类来处理不同类型的数据。

三、泛型接口

package com.pany.camp.base;public interface Pair<T, U> {T getFirst();U getSecond();
}

我们定义了一个泛型接口 Pair,它有两个类型参数 T 和 U,分别表示 Pair 中的两个元素的类型。Pair 接口有两个方法,getFirst() 和 getSecond(),用于获取 Pair 对象的两个元素。

package com.pany.camp.base;public class StringIntegerPair implements Pair<String, Integer> {private String first;private Integer second;public StringIntegerPair(String first, Integer second) {this.first = first;this.second = second;}@Overridepublic String getFirst() {return first;}@Overridepublic Integer getSecond() {return second;}
}

然后我们创建了一个 StringIntegerPair 类,它实现了 Pair 接口,并指定了 T 和 U 的具体类型为 String 和 Integer。StringIntegerPair 类有一个构造函数,用于初始化 StringIntegerPair 对象的两个元素。StringIntegerPair 类还实现了 Pair 接口的两个方法,用于获取 StringIntegerPair 对象的两个元素。

四、泛型方法

泛型方法可以让我们编写更加通用、可复用的代码,可以在不同的场景中使用相同的方法来处理不同类型的数据。

例子如下:

public static <T> int countOccurrences(T[] array, T element) {int count = 0;for (T value : array) {if (value.equals(element)) {count++;}}return count;
}

我们定义了一个泛型方法 countOccurrences,它有两个参数,一个是泛型类型数组 array,另一个是泛型类型元素 element。countOccurrences 方法的作用是统计数组中与 element 相等的元素个数。

String[] strings = {"foo", "bar", "baz", "foo"};
int count1 = countOccurrences(strings, "foo"); // 返回 2
int count2 = countOccurrences(strings, "qux"); // 返回 0Integer[] integers = {1, 2, 3, 2, 1};
int count3 = countOccurrences(integers, 2); // 返回 2
int count4 = countOccurrences(integers, 4); // 返回 0

我们分别使用了字符串类型数组和整数类型数组来调用 countOccurrences 方法,传入不同的元素来统计数组中相等的元素个数。

五、泛型的上下限

泛型的上下限是指在使用泛型时,可以限制泛型参数的类型范围,从而提高代码的类型安全性。上限限制了泛型参数的类型必须是某个类或其子类,下限限制了泛型参数的类型必须是某个类或其父类。
使用泛型的上下限可以避免类型转换错误,提高代码的类型安全性。

在 Java 中,可以使用 extends 关键字来指定泛型的上限,使用 super 关键字来指定泛型的下限。例如:

public class Box<T> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}// 使用 extends 指定泛型的上限
public class NumberBox<T extends Number> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}// 使用 super 指定泛型的下限
public class IntegerBox<T super Integer> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}

NumberBox 类使用 extends 指定泛型参数的上限为 Number 类型及其子类,因此只能使用 Number 类型及其子类作为泛型参数。而 IntegerBox 类使用 super 指定泛型参数的下限为 Integer 类型及其父类,因此只能使用 Integer 类型及其父类作为泛型参数。


http://www.ppmy.cn/news/258557.html

相关文章

蓝光播放器中应用的触摸芯片

蓝光高清播放机是区别于普通蓝光播放机的一种新型碟机产品&#xff0c;它的特点在于“一机两用”&#xff0c;即不仅可以播放蓝光碟片&#xff0c;还支持外接硬盘高清文件播放。对于大部分高清电影爱好者来说&#xff0c;蓝光高清播放机“一机两用”的独有功能使他们不再困扰于…

720phi10p 和 720p有什么区别_蓝光影碟机和普通影碟机有什么区别

市面上有蓝光影碟机&#xff0c;也有普通影碟机。蓝光影碟机和普通影碟机有什么区别&#xff1f;今日就由PChouse为你一一解答。 1、碟片兼容 蓝光播放机可以读取蓝光光碟BD以及兼容DVD、VCD、CD等碟片&#xff0c;还支持各种格式的蓝光3D碟片&#xff0c;但是普通DVD碟机无法读…

慢 SQL 优化之索引的作用是什么? | 京东云技术团队

前言 本文针对 MySQL 数据库的 InnoDB 存储引擎&#xff0c;介绍其中索引的实现以及索引在慢 SQL 优化中的作用。 本文主要讨论不同场景下索引生效与失效的原因。 慢SQL与索引的关系 慢SQL优化原则 数据库也是应用&#xff0c;MySQL 作为一种磁盘数据库&#xff0c;属于典…

天龙DBP-1611UD蓝光播放机回顾

天龙DBP-1611UD蓝光播放机回顾   天龙推出了两款新的蓝光播放器由6月发布的2010年&#xff0c;DBP - 1611UD和DBP - 2011UDCI。令人惊讶的是&#xff0c;这两个将全高清3D兼容。这是令人惊讶&#xff0c;因为天龙通常是缓慢的标志&#xff0c;当谈到新技术。不想牺牲品质以任…

一款LG BD550蓝光播放机回顾

一款LG BD550蓝光播放机回顾   的BD550是从LG的一个新的入门级蓝光播放器。其中四名新球员的LG推出了在2010年的BD550是最便宜的&#xff0c;加上根据200.00美元的价格范围。它是非常相似的BD570模型。两者之间最大的区别是&#xff0c;这种模式没有任何的Wi-Fi选项。然而&am…

3畅销的三星蓝光播放机比较

这是三个畅销的三星蓝光播放器&#xff0c;是BD-C6500&#xff0c;BD-C5500和BD-C6900的比较。   三星蓝光播放机#1畅销书&#xff1a;三星BD-C6500 1080p蓝光光盘播放机   技术细节   - 超薄设计(39毫米)   - 无线内置   - 互联网电视   - BD-Live(规格2.0)&#…

直播rmvb格式的DVD出来啦,RMDVD携手蓝光战寒冬!

和家人一起看DVD&#xff0c;心里梦着蓝光&#xff0c;有点梦想的日子才快乐&#xff0c;生活也是这样&#xff0c;每天吃着粗茶淡饭&#xff0c;心里想着海鲜鲍鱼的美味。蓝光播放机是大势所趋&#xff0c;也是我们广大百姓的追求&#xff0c;在这蓝光普及之前的日子&#xff…

蓝光蓝光系统服务器,蓝光盘库

蓝光盘库 蓝光盘库由放置光盘的光盘托(Tray)、自动换盘机械手(Robotic)和驱动器(Driver)三部分组成。蓝光盘库可放1~14台驱动器&#xff0c;兼容CD/DVD/BD等光学技术&#xff0c;库体搭载智能热插拔式盘&#xff0c;无需关机即可更换盘片。通过高速SAS端口与网络服务器相联&…