0

0

Java集合框架中的泛型与类型安全

P粉602998670

P粉602998670

发布时间:2026-01-19 16:22:50

|

240人浏览过

|

来源于php中文网

原创

泛型擦除后ArrayList和ArrayList运行时均为ArrayList。Java泛型是编译期特性,字节码无类型参数,JVM无法区分具体类型,故不能用于运行时类型判断或分支逻辑。

java集合框架中的泛型与类型安全

泛型擦除后,ArrayListArrayList 运行时是同一个类

Java 泛型是编译期特性,字节码里没有类型参数。你写 new ArrayList()new ArrayList(),运行时都只是 ArrayList。JVM 不知道你存的是字符串还是整数——所以不能靠泛型做运行时类型判断或分支逻辑。

常见错误现象:
– 试图用 instanceof 检查泛型类型,比如 list instanceof ArrayList,会编译报错;
– 在反射中调用 list.getClass() 得到的永远是 class java.util.ArrayList,不是带泛型的类型。

  • 需要获取泛型实际类型时,只能通过 FieldMethodParameterizedType 等反射接口,在声明处(如字段定义)提取,而非实例上
  • 若需运行时类型区分,得额外存一个 Class 参数,比如 new TypeWrapper(String.class)
  • 泛型擦除也意味着无法直接 new T(),必须用 clazz.getDeclaredConstructor().newInstance()

向原始类型(raw type)集合添加任意对象不会触发编译错误,但破坏类型安全

如果你声明 ArrayList list = new ArrayList();(没写泛型),编译器就放弃所有类型检查。你可以往里加 StringFileThread,全都不报错。但一旦后续用 (String) list.get(0) 强转,运行时就可能抛 ClassCastException

这种写法在遗留代码或反射场景中容易出现,尤其当方法签名返回 raw type 时(如某些老版本 API 返回 List 而非 List)。

立即学习Java免费学习笔记(深入)”;

  • 启用 -Xlint:unchecked 编译参数,能让 javac 报出“未经检查的调用”警告
  • IDE(如 IntelliJ)默认高亮 raw type 使用,点进去能看到 “Unchecked assignment” 提示
  • 不要用 @SuppressWarnings("unchecked") 掩盖问题,除非你明确做了类型校验(比如用 instanceof + 显式强转)

Collection.toArray() 返回 Object[],强制转型数组会失败

这是泛型与数组协变性冲突的经典坑:toArray() 方法不接受泛型参数,只返回 Object[]。如果你写 String[] arr = list.toArray();,编译直接失败,因为 Object[] 不能赋给 String[]

UQ云商B2B2C系统
UQ云商B2B2C系统

UQCMS云商是一款B2B2C电子商务软件 ,非常适合初创的创业者,个人及中小型企业。程序采用PHP+MYSQL,模板采用smarty模板,二次开发,简单方便,无需学习其他框架就可以自行模板设计。永久免费使用,操作简单,安全稳定。支持PC+WAP+微信三种浏览方式,支持微信公众号。

下载

正确做法是传入一个带类型的数组作为参数,例如:

String[] arr = list.toArray(new String[0]);

这里传 new String[0] 的作用不是为了容量(内部会重新分配),而是告诉方法“我要 String[]”。如果传 new String[list.size()],还能避免一次扩容。

  • null 会触发 NullPointerException
  • 传入过小的数组(如 new String[1]),方法仍返回正确大小的 String[],但会复用该数组仅当容量足够
  • 别用 (String[]) list.toArray() —— 这是运行时异常高发写法,多数情况抛 ClassCastException

泛型通配符 ? extends T? super T 决定读写边界

当你看到方法参数是 Collection extends Number>,说明它只读不写:可以调用 get() 得到 Number 或其子类,但不能 add(new Integer(1)),因为编译器不知道具体是 ArrayList 还是 ArrayList

反过来,Collection super Integer> 支持写入 Integer 及其子类(如 Long 如果它继承自 Integer?不,它不继承,所以实际能安全写的只有 Integer),但读出来只能当 Object 处理。

  • extends 用于“生产者”(Producer):适合从集合取数据,如 max(Collection extends Comparable>)
  • super 用于“消费者”(Consumer):适合往集合放数据,如 Collections.copy(List super T>, List extends T>)
  • 无界通配符 Collection> 只能调用 size()isEmpty()clear() 等不依赖元素类型的方法
泛型不是运行时契约,它是编译器帮你盯住类型的一双眼睛。一旦绕过它(raw type、反射、数组转型),就得自己扛住类型崩塌的风险——而这种崩塌往往发生在深夜上线后的第一个用户请求里。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

838

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

741

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

737

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

C# 教程
C# 教程

共94课时 | 7万人学习

Java 教程
Java 教程

共578课时 | 47.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号