`
hongan
  • 浏览: 174840 次
  • 性别: Icon_minigender_1
  • 来自: 佛山
社区版块
存档分类
最新评论

了解泛型

    博客分类:
  • Java
阅读更多

 

JDK 5.0(也叫做 Java 5.0 或者 Tiger)给 Java 语言带来了一些较大的变化。其中最重要的变化就是引入了泛型 —— 支持定义带有抽象类型参数的类,这些参数由您在实例化时指定。泛型为提高大型程序的类型安全和可维护性带来了很大的潜力。

泛型与 JDK 5.0 中其他几个新的语言特性相互协作,包括增强的 for 循环(有时叫做 foreach 或者 for/in 循环)、枚举(enumeration)和自动装箱(autoboxing)。

 

 什么是泛型?

泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

可以在集合框架(Collection framework)中看到泛型的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象。

因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:


Map m = new HashMap();
m.put("key", "blarg");
String s = (String) m.get("key");

要让程序通过编译,必须将 get() 的结果强制类型转换为 String,并且希望结果真的是一个 String。但是有可能某人已经在该映射中保存了不是 String 的东西,这样的话,上面的代码将会抛出 ClassCastException

理想情况下,您可能会得出这样一个观点,即 m 是一个 Map,它将 String 键映射到 String 值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。

泛型的好处

 

Java 语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处:

类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

Java 程序中的一种流行技术是定义这样的集合,即它的元素或键是公共类型的,比如“String 列表”或者“StringString 的映射”。通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误现在就可以在编译时被捕获了,而不是在运行时当作 ClassCastException 展示出来。将类型检查从运行时挪到编译时有助于您更容易找到错误,并可提高程序的可靠性。

消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。比较下面两个代码例子。

该代码不使用泛型:


List li = new ArrayList();
li.put(new Integer(3));
Integer i =  (Integer) li.get(0);

该代码使用泛型:


List<Integer> li = new ArrayList<Integer>();
li.put(new Integer(3));
Integer i =  li.get(0);

在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。

潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。

由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

泛型用法的例子

 

泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束。考虑这个使用 Map 类的例子,其中涉及一定程度的优化,即 Map.get() 返回的结果将确实是一个 String


Map m = new HashMap();
m.put("key", "blarg");
String s = (String) m.get("key");

如果有人已经在映射中放置了不是 String 的其他东西,上面的代码将会抛出 ClassCastException。泛型允许您表达这样的类型约束,即 m 是一个将 String 键映射到 String 值的 Map。这可以消除代码中的强制类型转换,同时获得一个附加的类型检查层,这个检查层可以防止有人将错误类型的键或值保存在集合中。

下面的代码示例展示了 JDK 5.0 中集合框架中的 Map 接口的定义的一部分:


public interface Map<K, V> {
  public void put(K key, V value);
  public V get(K key);
}

注意该接口的两个附加物:

 

类型参数 KV 在类级别的规格说明,表示在声明一个 Map 类型的变量时指定的类型的占位符。

 在 get()put() 和其他方法的方法签名中使用的 KV

 

为了赢得使用泛型的好处,必须在定义或实例化 Map 类型的变量时为 KV 提供具体的值。以一种相对直观的方式做这件事:


Map<String, String> m = new HashMap<String, String>();
m.put("key", "blarg");
String s = m.get("key");

当使用 Map 的泛型化版本时,您不再需要将 Map.get() 的结果强制类型转换为 String,因为编译器知道 get() 将返回一个 String

在使用泛型的版本中并没有减少键盘录入;实际上,比使用强制类型转换的版本需要做更多键入。使用泛型只是带来了附加的类型安全。因为编译器知道关于您将放进 Map 中的键和值的类型的更多信息,所以类型检查从执行时挪到了编译时,这会提高可靠性并加快开发速度。

分享到:
评论
1 楼 lhwci 2009-01-01  
说实话,并没有看到这玩意儿带来的真正意义上的好处,除了让代码看上去更加紊乱以外

相关推荐

    Java 理论和实践 了解泛型

    Java 理论和实践 了解泛型

    快速了解泛型(C#,JAVA,C++)

    泛型其实就是能够向你的类型中加入类型参数的一种能力,也称作参数化的类型或参数多态性

    C# 2.0中泛型编程思想分析

     本文讨论泛型使用的一般问题,比如为什么要使用泛型、泛型的编写方法、泛型中数据类型的约束、泛型中静态成员使用要注意的问题、泛型中方法重载的问、泛型方法等,通过这些使我们可以大致了解泛型并掌握泛型的一般...

    JAVA-泛型课件-泛型课件

    个人制作且上课使用的课件,希望对大家初步了解泛型相关内容有一定的帮助。个人制作且上课使用的课件,希望对大家初步了解泛型相关内容有一定的帮助。

    JAVA第八章 泛型.pptx

    了解泛型,能够说出泛型的作用和优点 掌握泛型类,能够独立定义和使用泛型类 掌握泛型接口,能够独立定义和使用泛型接口 掌握泛型方法,能够独立定义并使用泛型方法 掌握类型通配符,能够正确定义类型通配符的上限和...

    C# 2.0中泛型编程初级入门教程.pdf

    中静态成员使用要注意的问题、泛型中方法重载的问、泛型方法等,通过这些使我们可以大致了解泛型并掌握 泛型的一般应用,编写出更简单、通用、高效的应用系统。 什么是泛型 我们在编写程序时,经常遇到两个模块的...

    泛型编程.rar(源码及讨论)

    比如为什么要使用泛型、泛型的编写方法、泛型中数据类型的约束、泛型中静态成员使用要注意的问题、泛型中方法重载的问、泛型方法等,通过这些使我们可以大致了解泛型并掌握泛型的一般应用,编写出更简单、通用、高效...

    C++f 泛型编程应用实例

    集合了C++多重泛型应用实例,让初学者能够了解泛型编程的魅力,为学好C++ 打下良好基础。

    C# 泛型委托示例 应用解析

    这是一个泛型委托的示例,主要是让初学者了解泛型委托的用法,虽然很简单,但是代码有注释,我的这个例子是在vs2010中做的,用vs08的朋友们,最好还是转一下,但是绝对能实现(本程序是控制台应用程序,适合初学者)...

    如何使用泛型集合

    如何使用泛型和泛型集合,更好的了解泛型和泛型集合

    java泛型简单明了.md

    对泛型的简单举例,通过例子了解泛型这个知识点

    java中的泛型样例

    一些简单的关于泛型的样例,它能让你基本了解泛型。。。。

    Java集合框架及泛型

    集合框架及泛型的介绍和基础理解,方便大家了解集合框架及泛型。

    习----题-Java-Web程序设计教程-[共2页].pdf

    如果要深 入了解泛型编程,请查阅相关资料。 习 题 上机实践 1.将本学期开设的课程名称加入到 HashSet 中,并使用迭代器遍历输出。 2.调试书本上 TreeSet 的例子,理解其原理。 3.完成以下实验: (1)定义一个...

    Webservice传递泛型的案例,包括web服务端和mobile端

    Webservice传递泛型的案例,包括web服务端和mobile端。让你快速的了解Webservice和mobile传递泛型的方法。

    使用泛型和并发改善集合

    本文内容包括:了解泛型泛型编译器问题读取网页线程池其他线程池结束语下载参考资料Java:trade_mark:CollectionsFramework是Java平台的一个重要部分。桌面和企业应用程序通常都使用该框架来聚集集合项。本文将向您...

    c#泛型学习详解 创建线性链表

    术语表 ...我相信这是因为他们通常在了解泛型是用来解决什么问题之前,就被灌输了大量的理论和范例。结果就是你有了一个解决方案,但是却没有需要使用这个解决方案的问题。 这篇文章将尝试着改变这种

    Java泛型实例

    一个可以让你对Java泛型更加深入了解的下例子。

    基于泛型和反射的三层架构雏形(另一个旧版不能删除)

    同时,因为反射会带来性能损失,因此,可根据自己需求,针对每个类型轻松在两种模式之前切换,本例源码,测试实例俱全,而且代码浅显易懂,只要对泛型、反射、三层架构有一定了解的人都能轻松学习

Global site tag (gtag.js) - Google Analytics