当前位置: 首页 > news >正文

135. Java 泛型 - 无界通配符

文章目录

  • 135. Java 泛型 - 无界通配符 (`?`)
    • **1. 什么是无界通配符 (`?`)?**
    • **2. 为什么使用无界通配符?**
    • **3. 示例:使用 `?` 处理任意列表**
      • **❌ 错误示例**
      • **✅ 正确示例**
    • **4. 为什么 `List<Object>` 和 `List<?>` 不一样?**
      • **❌ 错误示例**
    • **5. 适用场景**
    • **6. 结论**

135. Java 泛型 - 无界通配符 (?)

在 Java 泛型中,无界通配符 (?) 允许表示任何类型,使代码更加通用。

本篇将详细讲解无界通配符的概念,并结合示例帮助理解。


1. 什么是无界通配符 (?)?

无界通配符 ? 代表“未知类型”,它可以用于泛型类或泛型方法,使其适用于任意类型

例如:

List<?> list;
  • list 可以接受 List<String>List<Integer>List<Double> 等任何类型的 List
  • 但由于 ? 代表未知类型,无法向 list 中添加元素(除了 null)。

2. 为什么使用无界通配符?

无界通配符适用于以下两种情况:

  1. 仅使用 Object 类的方法,而不需要特定类型的方法(如 toString()equals()hashCode())。
  2. 方法的逻辑不依赖于泛型类型参数,如 List.size()List.clear()

无界通配符的语法

List<?> list = new ArrayList<String>();
  • 这里 list 可以引用任何类型ListList<Integer>List<Double> 等)。
  • 但是,我们不能向 list 添加元素(除了 null)。

3. 示例:使用 ? 处理任意列表

📌 需求:编写一个方法,能够打印任何类型的 List,包括 List<String>List<Integer>List<Double> 等。

❌ 错误示例

以下代码无法打印 List<Integer>,因为 List<Integer> 不是 List<Object> 的子类:

public static void printList(List<Object> list) { // ❌ 只能接受 List<Object>for (Object elem : list)System.out.println(elem);
}public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3);printList(numbers); // ❌ 编译错误
}

🔍 为什么?

  • List<Integer> 不是 List<Object> 的子类(因为泛型是不协变的)。
  • Java 泛型中的 List<T>不可变更类型的,即 List<Integer>List<Object> 没有继承关系。

✅ 正确示例

import java.util.Arrays;
import java.util.List;public class UnboundedWildcard {public static void printList(List<?> list) { // ✅ 适用于任何 List 类型for (Object elem : list) { // ✅ 安全读取元素System.out.print(elem + " ");}System.out.println();}public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3);List<String> words = Arrays.asList("Hello", "World");List<Double> decimals = Arrays.asList(1.1, 2.2, 3.3);printList(numbers); // 输出: 1 2 3 printList(words);   // 输出: Hello World printList(decimals); // 输出: 1.1 2.2 3.3}
}

🔍 解析

  • printList(List<?>) 可以接受任何 List<T>,如 List<Integer>List<String>List<Double> 等。
  • Object elem 安全读取 list 的元素,因为所有 Java 对象最终都继承自 Object
  • 但我们不能向 list 添加元素(除了 null)。

4. 为什么 List<Object>List<?> 不一样?

在 Java 泛型中,List<Object>List<?> 并不相同

  1. List<Object> 只能存储 Object 及其子类,但不能存储 IntegerString,因为 List<Integer> 不是 List<Object> 的子类。
  2. List<?> 可以存储任何类型的 List,但由于类型未知,无法向 List<?> 添加元素(除了 null)。

❌ 错误示例

List<?> unknownList = new ArrayList<Integer>();
unknownList.add(5); // ❌ 编译错误
unknownList.add("Hello"); // ❌ 编译错误
unknownList.add(null); // ✅ 允许

🔍 为什么?

  • unknownList 可以引用 List<Integer>List<String>List<Double>,但Java 无法确定具体的类型,所以不允许添加元素。
  • 但**null 可以插入**,因为 null 适用于任何类型。

5. 适用场景

适用于不关心具体类型的 List(如通用的 printList 方法)。
适用于使用 Object 方法的情况(如 toString()size()clear())。
适用于泛型方法,使代码更加灵活


6. 结论

? 表示“未知类型”,可以匹配任意泛型类型
List<?> 可以存储 List<T> 的任何类型,但不能添加元素(除了 null
List<?>List<Object> 不同,前者适用于任何 List<T>,而后者仅适用于 List<Object>
使用 ? 让代码更加通用,提高可复用性


🎯 记住口诀:

  • 无界通配符 ? 适用于“只读”数据(与 Object 兼容)
  • List<?> 不能添加元素,避免类型不安全问题
  • List<?> 适用于“泛型无关”的方法,如 size()clear()toString()

🚀 学会 ?,让你的 Java 泛型代码更灵活!

http://www.lryc.cn/news/592059.html

相关文章:

  • Android CountDownTimer
  • Ubuntu系统下交叉编译Android的X265库
  • UVC for USBCamera in Android - 篇二
  • 股指期货的杠杆比例一般是多少?
  • 【软件系统架构】系列七:系统性能——路由器性能深入解析
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - jieba库分词简介及使用
  • 短视频矩阵系统哪家好?全面解析与推荐
  • 短视频矩阵系统:从源头到开发的全面解析
  • 【unity实战】使用unity的Navigation+LineRenderer实现一个3D人物寻路提前指示预测移动轨迹的效果,并可以适配不同的地形
  • Charles 中文版介绍与使用指南 强大抓包工具助力 API 调试与网络优化
  • 网络编程(modbus,3握4挥)
  • 新书推介 | 吉林大学出版教材《汽车智能辅助驾驶系统技术》,国产仿真工具链GCKontrol-GCAir教学应用
  • mybatisdemo(黑马)
  • S7-1200 Profinet 的诊断功能
  • 嵌入式教育的云端革命:零边界实验室如何重塑未来工程师
  • 硬核电子工程:从硅片到系统的全栈实战指南—— 融合电路理论、嵌入式开发与PCB设计的工程艺术
  • 第三章自定义检视面板_创建自定义编辑器类_检测与应用修改(本章进度(2/9))
  • Xilinx Zynq:一款适用于软件定义无线电的现代片上系统
  • 深度学习之----对抗生成网络-pytorch-CycleGAN-and-pix2pix
  • IP协议深入理解
  • RustDesk 自建中继服务器教程(Mac mini)
  • 蓝松抠图的几大优点.
  • Vue中的refs字段使用记录
  • (数据结构)线性表(上):SeqList 顺序表
  • k8s:利用kubectl部署postgis:17-3.5
  • Kotlin序列
  • CloudFabric解决方案
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • HTTP 性能优化:五条建议
  • 线程安全集合——ConcurrentHashMap