java中问号?的用法

在 Java 中,问号 ? 符号主要在泛型(generics)中使用,称为通配符(wildcard)。通配符用于指定类型参数的上限、下限或不确定的类型。以下是通配符的几种常见用法:

1. 无界通配符(Unbounded Wildcard)

无界通配符使用 ? 表示,可以匹配任何类型。主要用于方法参数和返回值类型不确定的情况。

复制代码
public void printList(List<?> list) {
    for (Object elem : list) {
        System.out.println(elem);
    }
}

List<String> stringList = Arrays.asList("apple", "banana", "cherry");
List<Integer> intList = Arrays.asList(1, 2, 3);

printList(stringList); // 可以传入任意类型的List
printList(intList);

2. 上界通配符(Upper Bounded Wildcard)

上界通配符使用 ? extends Type 表示,表示类型参数可以是 Type 或其子类。主要用于只读场景,即从集合中读取数据但不修改集合。

复制代码
public void printNumbers(List<? extends Number> list) {
    for (Number num : list) {
        System.out.println(num);
    }
}

List<Integer> intList = Arrays.asList(1, 2, 3);
List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3);

printNumbers(intList); // 可以传入Number及其子类的List
printNumbers(doubleList);

3. 下界通配符(Lower Bounded Wildcard)

下界通配符使用 ? super Type 表示,表示类型参数可以是 Type 或其父类。主要用于写场景,即可以向集合中添加数据。

复制代码
public void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
    list.add(3);
}

List<Number> numberList = new ArrayList<>();
addNumbers(numberList); // 可以传入Integer及其父类的List
System.out.println(numberList); // 输出:[1, 2, 3]

示例总结

  • 无界通配符 ?:用于表示未知类型,适用于任何类型。
  • 上界通配符 ? extends Type:用于限制类型参数为某个类型或其子类,适用于只读操作。
  • 下界通配符 ? super Type:用于限制类型参数为某个类型或其父类,适用于写操作。

通配符的使用场景

  • 只读访问:如果只需要读取集合中的数据,可以使用上界通配符。
  • 写入操作:如果需要向集合中添加数据,可以使用下界通配符。
  • 不确定类型:如果不确定集合的具体类型,可以使用无界通配符。

通配符和泛型方法的对比

泛型方法在定义时使用类型参数,而通配符在方法参数中使用。

泛型方法示例
复制代码
public <T> void printArray(T[] array) {
    for (T element : array) {
        System.out.println(element);
    }
}

String[] stringArray = {"apple", "banana", "cherry"};
Integer[] intArray = {1, 2, 3};

printArray(stringArray); // 使用泛型方法
printArray(intArray);

总结

  • 通配符 ? 是 Java 泛型的一部分,用于表示未知类型。
  • 使用通配符可以使代码更加灵活和通用,适应多种类型。
  • 理解上界通配符和下界通配符的区别和应用场景,可以编写出更高效和安全的泛型代码。

通过合理使用泛型和通配符,可以提高代码的重用性和类型安全性,减少类型转换和类型检查的需求。

相关推荐
哦虎!4 小时前
【JavaEE】网络初识
java
for_ever_love__5 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
程序猿追6 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播6 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
欣栀♡6 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室6 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项6 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
墨云安全6 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php