java 泛型学习

本文深入解析Java泛型的使用,强调命名类型参数的约定,并解释为什么泛型不支持协变,以及这种设计背后的逻辑。通过示例代码演示了泛型在不同场景下的应用与限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

除了异常类型、枚举或匿名内部类以外,任何类都可以具有类型参数。
命名类型参数
推荐的命名约定是使用大写的单个字母名称作为类型参数。这与C++ 约定有所不同(参阅附录 A:与 C++ 模板的比较),并反映了大多数泛型类将具有少量类型参数的假定。对于常见的泛型模式,推荐的名称是:

* K —— 键,比如映射的键。
* V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。
* E —— 异常类。
* T —— 泛型。

泛型不是协变的
关于泛型的混淆,一个常见的来源就是假设它们像数组一样是协变的。其实它们不是协变的。List<Object>不是List<String>的父类型。
如果 A 扩展 B,那么 A 的数组也是 B 的数组,并且完全可以在需要B[]的地方使用A[]:

Integer[] intArray = new Integer[10];

Number[] numberArray = intArray;

上面的代码是有效的,因为一个Integer是一个Number,因而一个Integer数组是一个Number数组。但是对于泛型来说则不然。下面的代码是[b][size=x-large]无效[/size][/b]的:

List<Integer> intList = new ArrayList<Integer>();

List<Number> numberList = intList; // invalid


最初,大多数 Java 程序员觉得这缺少协变很烦人,或者甚至是“坏的(broken)”,但是之所以这样有一个很好的原因。如果可以将List<Integer>赋给List<Number>,下面的代码就会违背泛型应该提供的类型安全:

public static void main(String[] args) {
Integer[] integers = new Integer[5];
Number[] numbers = integers;
System.out.println(numbers[0]);// null
numbers[0] = new Float(7.65);
System.out.println(numbers[0]);
System.out.println(integers[0]);

List<Integer> list = new ArrayList<Integer>();
//这行代码无法编译,Type mismatch: cannot convert from List<Integer> to List<Number>
List<Number> listObj = list;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值