Java 泛型的用法

ops/2025/1/12 14:06:07/

1. 泛型类

泛型类是指在类定义时使用类型参数来指定类的类型。这样可以在类的内部使用这些类型参数来定义字段、方法的返回类型和参数类型。

java">public class Box<T> {private T t;public void set(T t) {this.t = t;}public T get() {return t;}
}

在这个例子中,Box 类使用了一个类型参数 T,可以在创建 Box 对象时指定具体的类型。

java">Box<Integer> integerBox = new Box<>();
integerBox.set(10);
Integer value = integerBox.get();Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String message = stringBox.get();

2. 泛型接口

泛型接口与泛型类类似,允许在接口定义时使用类型参数。

java">public interface Cache<K, V> {V get(K key);void put(K key, V value);
}public class MemoryCache<K, V> implements Cache<K, V> {private Map<K, V> map = new HashMap<>();@Overridepublic V get(K key) {return map.get(key);}@Overridepublic void put(K key, V value) {map.put(key, value);}
}

在这个例子中,Cache 接口使用了两个类型参数 K 和 V,分别表示键和值的类型。MemoryCache 类实现了 Cache 接口,并使用了这些类型参数。

java">Cache<String, Integer> cache = new MemoryCache<>();
cache.put("one", 1);
Integer number = cache.get("one");

3. 泛型方法

泛型方法是指在方法定义时使用类型参数。这样可以在方法内部使用这些类型参数来定义方法的返回类型和参数类型。

java">public class Util {public static <T> T getFirst(T[] array) {if (array == null || array.length == 0) {return null;}return array[0];}
}

在这个例子中,getFirst 方法使用了一个类型参数 T,可以在调用方法时指定具体的类型。

java">Integer[] intArray = {1, 2, 3};
Integer firstInt = Util.getFirst(intArray);String[] stringArray = {"Hello", "World"};
String firstString = Util.getFirst(stringArray);

4. 类型通配符

类型通配符 ? 用于表示未知类型,可以用于方法参数和返回类型,以提高代码的灵活性。

无界通配符:? 表示任意类型。
java">public void printList(List<?> list) {for (Object elem : list) {System.out.print(elem + " ");}System.out.println();
}

}

有界通配符:

上界通配符:? extends T 表示类型参数是 T 的子类型。
java">public static double sumOfList(List<? extends Number> list) {double s = 0.0;for (Number n : list) {s += n.doubleValue();}return s;
}

下界通配符:? super T 表示类型参数是 T 的父类型。

java">public static void addNumbers(List<? super Integer> list) {for (int i = 1; i <= 10; i++) {list.add(i);}
}

5. 泛型的类型擦除

Java 泛型在编译时会被擦除,即编译后的字节码中不包含泛型信息。这意味着在运行时,泛型类型参数会被替换为它们的上界(如果有上界)或 Object(如果没有上界)。

java">public class Box<T> {private T t;public void set(T t) {this.t = t;}public T get() {return t;}
}

编译后,Box 类的字节码中 T 会被替换为 Object:

java">public class Box {private Object t;public void set(Object t) {this.t = t;}public Object get() {return t;}
}

6. 泛型的限制

不能使用基本数据类型:泛型只能使用对象类型,不能使用基本数据类型。例如,不能创建 Box,但可以创建 Box。
类型参数不能是 final 类型:不能使用 final 类型作为类型参数。
静态上下文中不能使用类型参数:不能在静态方法或静态初始化块中使用类的类型参数。
类型参数不能是异常类型:不能使用异常类型作为类型参数。


http://www.ppmy.cn/ops/149473.html

相关文章

25年无人机行业资讯 | 1.1 - 1.5

25年无人机行业资讯 | 1.1 - 1.5 中央党报《经济日报》刊文&#xff1a;低空经济蓄势待发&#xff0c;高质量发展需的平衡三大关系 据新华网消息&#xff0c;2025年1月3日&#xff0c;中央党报《经济日报》发表文章指出&#xff0c;随着国家发展改革委低空经济发展司的成立&a…

使用JMeter模拟多IP发送请求!

你是否曾遇到过这样的场景&#xff1a;使用 JMeter 进行压力测试时&#xff0c;单一 IP 被服务器限流或者屏蔽&#xff1f;这时&#xff0c;如何让 JMeter 模拟多个 IP 发送请求&#xff0c;成功突破测试限制&#xff0c;成为测试工程师必须攻克的难题。今天&#xff0c;我们就…

交响曲-24-3-单细胞CNV分析及聚类

CNV概述 小于1kb是常见的插入、移位、缺失等的变异 人体内包含<10% 的正常CNV&#xff0c;我们的染色体数是两倍体&#xff0c;正常情况下&#xff0c;只有一条染色体表达&#xff0c;另一条沉默&#xff0c;当表达的那条染色体发生CNV之后&#xff0c;表达数量就会成倍增加…

【UE5 C++课程系列笔记】27——多线程基础——ControlFlow插件的基本使用

目录 步骤 一、搭建基本同步框架 二、添加委托 三、添加蓝图互动框架 四、修改为异步框架 完整代码 通过一个游戏初始化流程的示例来介绍“ControlFlows”的基本使用。 步骤 一、搭建基本同步框架 1. 勾选“ControlFlows”插件 2. 新建一个空白C类&#xff0c;这里…

<C++学习>C++ Boost 与 std 的对比

Boost 与 std 的对比 Boost 和 std(C++ 标准库)是 C++ 开发中两个重要的工具集,它们在设计理念、功能范围和使用方式上存在一些差异。以下是详细的比较和分析: 1. 定义与背景 Boost 来源:Boost 是一个开源的 C++ 库集合,由志愿者开发,首次发布于 1998 年。目标:提供高…

JavaScript系列(20)-- Generator应用详解

JavaScript Generator应用详解 &#x1f31f; 今天&#xff0c;让我们深入探讨JavaScript中Generator的应用。Generator是ES6引入的强大特性&#xff0c;它为异步编程和迭代提供了优雅的解决方案。 Generator基础回顾 &#x1f3af; &#x1f4a1; 小知识&#xff1a;Generat…

JavaEE之定时器及自我实现

在生活当中&#xff0c;有很多事情&#xff0c;我们不是立马就去做&#xff0c;而是在规定了时间之后&#xff0c;在到该时间时&#xff0c;再去执行&#xff0c;比如&#xff1a;闹钟、定时关机等等&#xff0c;在程序的世界中&#xff0c;有些代码也不是立刻执行&#xff0c;…

Linux文件系统的安全保障---Overlayroot!

overlayroot 是一种使用 OverlayFS 实现的功能&#xff0c;可将根文件系统挂载为只读&#xff0c;并通过一个临时的写层实现对文件系统的修改。这种方法非常适合嵌入式设备或需要保持系统文件完整性和安全性的场景。下文以 RK3568 平台为例&#xff0c;介绍制作 overlayroot 的…