`
hongan
  • 浏览: 176495 次
  • 性别: 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 泛型是Java编程语言中的一个重要特性,它在JDK 5.0版本中引入,目的是为了提高代码的类型安全性和重用性。泛型允许程序员在定义类、接口和方法时,指定一个或多个类型参数,这些参数在实际使用时会被具体的类型...

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

    泛型是现代编程语言中一个强大的特性,它允许程序员在编写代码时定义和使用类型参数,从而实现更灵活、安全的代码复用。这个概念在C#、Java和C++等面向对象的语言中都有所体现,尽管它们的具体实现和语法略有不同。...

    Java泛型应用实例

    配合博主的博客文章,你可以更深入地了解泛型在实际项目中的应用,包括但不限于类型安全的容器、泛型与反射的交互、以及泛型在并发编程中的作用等。通过实践这些实例,你将能够更好地掌握Java泛型的精髓,提高编程...

    泛型 反射 相关概念方法使用

    首先,我们来了解泛型。泛型是Java 5引入的一项特性,它允许在定义类、接口和方法时指定类型参数,以增强代码的类型安全性和可读性。通过使用泛型,我们可以限制容器(如集合)中存储的元素类型,避免在运行时进行...

    Java泛型编程最全总结

    首先,我们来了解泛型的基本概念。泛型类是在声明类时,将类型参数作为类的一部分,例如`ArrayList&lt;T&gt;`,这里的`T`就是一个类型参数,代表了某种未知的数据类型。在创建对象时,我们可以指定`T`的具体类型,如`...

    C#常用泛型类型.rar

    - 对于初学者,先了解泛型的基本概念,然后通过阅读和运行提供的代码实例,逐步理解`Dictionary, TValue&gt;`和`List&lt;T&gt;`的用法。 - 对于进阶开发者,可以进一步研究这两种泛型容器的内部实现,了解其性能特性,以及...

    泛型的原理,通俗解释

    在本文中,我们将通过一个通俗的解释来了解泛型的原理。 首先,什么是泛型?泛型可以定义类型安全的类,而不会损害类型安全、性能或工作效率。例如,以下是一个使用泛型的示例代码: ```csharp Public class Stack...

    Java源码泛型类的继承应用.rar

    首先,让我们来了解泛型类的基本概念。泛型类是在定义类时引入类型参数的类,形如`&lt;T&gt;`,其中`T`是类型参数的占位符,可以代表任何引用类型。例如,一个简单的泛型类定义如下: ```java public class GenericClass...

    泛型编程与伴随.pdf

    - 对于希望深入了解泛型编程和范畴论的读者来说,本文档提供了一个很好的起点。 - 通过本文档的学习,读者不仅能掌握伴随的基本概念,还能了解到其在编程实践中的具体应用。 综上所述,伴随不仅是一种理论上的构造,更是...

    泛型实际应用(简介)

    为了更进一步地利用泛型,我们需要了解泛型约束的概念。这些约束允许我们指定泛型类型的限制条件,使得某些操作成为可能或者更加高效。 - **泛型类型参数的约束**: - 示例:定义一个泛型链表类 `LinkedList, T&gt;` ...

    泛型的使用

    在深入研究开源项目时,了解泛型的使用有助于理解代码逻辑。例如,`ArrayList`的源码中,可以看到泛型是如何应用于数据结构的: ```java public class ArrayList&lt;E&gt; extends AbstractList implements List, Random...

    Java泛型研究.pdf

    Java泛型研究 Java泛型是Java语言中的一种重要机制,自从Java 1.5版本引入泛型以来,Java开发者可以更方便地编写...开发者需要了解泛型的基本概念、作用、应用和注意事项,以便更好地使用泛型提高代码的质量和安全性。

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

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

    c# 泛型保存类结构,支持递归

    首先,我们需要了解泛型的基本概念。泛型提供了一种方式,让我们可以创建不依赖具体类型的类型或方法。在定义泛型类、接口或方法时,我们会使用尖括号 `&lt;T&gt;` 来表示一个或多个类型参数。例如,`List&lt;T&gt;` 是一个常见...

    Repeater和泛型数据结合的简单例子

    接下来,我们要了解泛型。泛型允许我们在编写类、接口、方法时,不指定具体的类型,而是使用类型参数。在运行时,这些类型参数会被实际的类型替换,从而提供类型安全性和性能优化。例如,我们可以创建一个泛型列表`...

    Java泛型和集合-英文版

    根据提供的文件信息,我们可以确定本书的标题为《Java泛型和集合》(Java Generics and Collections),作者为Maurice Naftalin和Philip Wadler。...本书适合有一定Java基础并希望深入了解泛型和集合框架的读者。

    简单的泛型模拟实现

    通过阅读并理解这个文件的内容,你可以更深入地了解泛型的工作原理和用法。此外,泛型还可以与其他Java特性结合使用,比如接口、抽象类、枚举等,以提供更加复杂和灵活的设计模式。 泛型还有几个关键特性值得了解:...

    MyGeneric_amounttv7_泛型专题_

    首先,我们来了解泛型的声明。在Java中,我们可以使用尖括号`&lt;&gt;`来声明泛型。例如,我们创建一个泛型列表,可以声明为`List&lt;T&gt;`,这里的`T`就是类型参数,代表任意类型。开发者可以在使用时指定具体的类型,如`List...

Global site tag (gtag.js) - Google Analytics