千家信息网

为什么不要在新代码中使用原生态类型

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章主要介绍"为什么不要在新代码中使用原生态类型",在日常操作中,相信很多人在为什么不要在新代码中使用原生态类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"为什么
千家信息网最后更新 2025年01月31日为什么不要在新代码中使用原生态类型

这篇文章主要介绍"为什么不要在新代码中使用原生态类型",在日常操作中,相信很多人在为什么不要在新代码中使用原生态类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"为什么不要在新代码中使用原生态类型"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Java1.5 发行版增加了泛型(Generic)。
泛型出现前,集合读取的每个对象都必须进行转换,如果不小心插入类型错误对的对象,运行时的转换处理会报错。
泛型出现后,我们通过泛型可以告诉编译器每个集合可以接受哪些对象类型,让编译器自动为集合的元素插入进行转化,并且在编译时告知我们是否插入了类型错误的对象。

一些泛型的专业术语

泛型类或泛型接口:声明中具有一个或多个类型参数(type parameter)的类或者接口,统称为泛型。eg,jdk1.5之后,List 接口只有单个类型参数E,表示列表的元素类型,所以他的接口名称应该是List,但是人们常常把它简称为List。

参数化的类型(parameterized type),构成格式是:类或接口的名称 + 尖括号(<>)将泛型形式参数的实际类型参数列表括起来。

每个泛型都定义类一个 原生态类型(raw type),即不带任何实际类型参数的泛型名称。eg,List 对应的原生态类型是List。原生态类型就相当于从类型声明中删除了泛型信息。


泛型:编译期及早发现错误

使用泛型进行编码,有两个好处:

  • 优点1:让编写代码时在编译期及早发现错误,并且助于定位报错位置
  • 优点2:集合使用泛型,从集合中遍历元素时不需要再进行手工转换了 (编译器替我们完成隐式转换,并确保过程不会失败,无论我们使用的是否for-each循环)


下面我们通过一个例子阐述清楚,代码如下:

  /**   * @exception ClassCastException   */  private static void testGenericeBeforejdk5() {    Collection stamps = new ArrayList();    stamps.add(new Coin());    for (Iterator i = stamps.iterator(); i.hasNext();){      Stamp next = (Stamp)i.next(); //ClassCastException    }  }  private static void testGenericeAfterjdk5() {    Collection stamps = new ArrayList();    stamps.add(new Coin());//编译器告诉我们错误  }    // 两个测试内部类  static class Stamp{}  static class Coin{}
  • testGenericeBeforejdk5()方法里,我们希望stamps集合只会存放Stamp 类元素,但是编码时还是不小心把一个coin放进了这个集合。那么程序是不会在编译时告诉程序员这个问题的,而是等到代码真正执行时,出现了异常。
Exception in thread "main" java.lang.ClassCastException: effectivejava.no23.TestGeneric$Coin cannot be cast to effectivejava.no23.TestGeneric$Stamp  at effectivejava.no23.TestGeneric.testGenericeBeforejdk5(TestGeneric.java:26)  at effectivejava.no23.TestGeneric.main(TestGeneric.java:14)

  • testGenericeAfterjdk5()方法里,我们使用了泛型定义了集合的参数类型。通过这条声明,编译器知道 stamps 集合应该只包含Stamp 实例,并给以保证。因此在代码开发时,我们不小心将一个coin 实例放进stamps集合时,编译器会及时提醒我们并产生一条编译错误信息,准确告知程序员哪里出现错误。

Error:(20, 28) java: 不兼容的类型: effectivejava.no23.TestGeneric.Coin无法转换为effectivejava.no23.TestGeneric.Stamp
  • 通过比较,我们还能发现,集合使用泛型,从集合中遍历元素时不需要再进行手工转换了。

原生类型与泛型类型的区别

其一、使用原生态类型,会失掉泛型在安全性和其他表述性方面的优势。

为什么继续允许使用原生态类型呢?Java 平台发展至今,已经存在大量的没有使用泛型的Java 代码了,人们认为让所有这些代码保持合法,且能够与泛型的代码互用,为了这个"移植兼容性"(Migration Compatibility)需求,促成了支持原生态类型的决定。

其二、原生态类型List 和 参数化类型List有区别。