不要使用原始类型

Posted lillill

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不要使用原始类型相关的知识,希望对你有一定的参考价值。

 

 

首先,来介绍几个术语。泛型类或接口是指,声明里有一个或多个类型参数的类或接口[JLS, 8.1.2, 9.1.2]。例如,List接口就有一个类型参数,E,它表示了List的元素类型。接口的全名是List(读作“E的列表”),但人们通常简称它为列表。泛型类和接口都被称为泛型类型

每个泛型类型都定义了一组参数化的类型,它的组成形式为,类名或者接口名后面跟着由尖括号包围的类型参数列表,列表里的每个参数都对应着泛型类型的形式类型参数[JLS, 4.4, 4.5]。例如,List(读作字符串列表)就是一个参数化的类型,代表了元素是String类型的列表。(String是形式类型参数E的实际类型参数。)

最后,每个泛型类型定义了一个原始类型,即不带任何类型参数的泛型类型的名称。例如,List对应的原始类型是List。原始类型看起来就像将所有的泛型类型信息从类型声明了去除了一样。它们的存在主要是为了兼容那些之前在泛型未出现时写的代码。

在泛型被添加进Java之前,下面的例子是一个标准的集合声明。对于Java 9,这么声明仍然是合法的,但就并不是典型的声明了

 
 
 
?x
 
 
 
 
1
private final Collection stamps = ... ;
 
 

如果到今天你还是用这种声明然后不小心往Stamp集合里放入了一个Coin对象,这种错误插入仍然可以编译而且运行也不会出错(虽然编译器会发出一个不明确的警告)

在你尝试从这个Stamp集合里获取Coin对象之前,你都不会遇到程序错误

正如本书提到的,出现错误后最好尽快发现,理想情况是在编译时就发现。在上面例子的情况下,直到运行时你才能发现问题,那时问题已经出现很久了,而且真正有问题的代码可能离直接出错的地方很远。在你看到ClassCastException后,你不得不搜索整个代码库,找出将Coin对象放入Stamp集合的方法调用。编译器无法提供帮助,因为它无法理解那句注释:只能包含Stamp实例。

当你从集合里获取元素时,编译器默默帮你做了强转的工作,保证了取出的元素是符合要求的(假设你所有的代码没有生成或抑制任何编译警告)。虽然不大可能将Coin对象插入Stamp集合里,但这个问题的确是存在的。例如,不难想象出将一个BigInteger放入一个本应该只能包含BigDecimal的集合。

,使用原始类型(不包含类型参数的泛型类)是合法的,但你永远都不应该这么做。如果你使用了原始类型,你将会失去泛型所带来的安全性和可读性

如果使用诸如List之类的原始类型,你将失去类型安全,但如果你使用了一个像List<Object>那样的参数化类型,则没有这个问题

以上是关于不要使用原始类型的主要内容,如果未能解决你的问题,请参考以下文章

不要在片段中显示列表视图项

为什么原始数据类型在不包含System命名空间的情况下工作

“不要保留活动” - 当应用程序恢复时,片段仅可见一秒钟

为什么我不能在此片段中生成唯一对象数组?

Solr 高亮是不是还可以指示返回的片段在原始字段中的位置或偏移量?

在代码片段中包含类型转换