`
anxin587
  • 浏览: 24073 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

转贴 java 泛型,辛苦译者了

    博客分类:
  • JAVA
阅读更多

Java1.5泛型指南中文版(Java1.5 Generic Tutorial)<o:p></o:p>

英文版pdf下载链接:http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

                                                 译者: chengchengji@163.com

<o:p> </o:p>

        <o:p></o:p>

<o:p> </o:p>

摘要和关键字... 1<o:p></o:p>

1.       介绍... 1<o:p></o:p>

2.       定义简单的泛型... 2<o:p></o:p>

3.       泛型和子类继承... 3<o:p></o:p>

4.       通配符(Wildcards). 4<o:p></o:p>

4.1.       有限制的通配符(Bounded Wildcards). 5<o:p></o:p>

5.       型方法... 6<o:p></o:p>

6.       与旧代码交互... 9<o:p></o:p>

6.1.       在泛型代码中使用老代码... 9<o:p></o:p>

6.2.       擦除和翻译(Erasure and Translation). 10<o:p></o:p>

6.3.     在老代码中使用泛型代码... 11<o:p></o:p>

7.       要点(The Fine Print). 12<o:p></o:p>

7.1.       一个泛型类被其所有调用共享... 12<o:p></o:p>

7.2.       转型和instanceof 13<o:p></o:p>

7.3.       数组Arrays. 13<o:p></o:p>

8.       Class Literals as Run-time Type Tokens. 14<o:p></o:p>

9.       More fun with *. 16<o:p></o:p>

9.1.       通配符匹配(wildcard capture). 18<o:p></o:p>

10.     泛型化老代码... 18<o:p></o:p>

11.     致谢... 20<o:p></o:p>

<o:p> </o:p>

摘要和关键字<o:p></o:p>

       genericstype safetype parameter(variable)formal type parameteractual type parameterwildcards(?)unknown type? extends T? super TerasuretranslationcastinstanceofarraysClass Literals as Run-time Type Tokenswildcard capturemultiple bounds(T extends T1& T2 ... & Tn)covariant returns<o:p></o:p>

      <o:p></o:p>


<o:p> </o:p>

1.            介绍<o:p></o:p>

JDK1.5中引入了对java语言的多种扩展,泛型(generics)即其中之一。<o:p></o:p>

这个教程的目标是向您介绍java的泛型(generic)。你可能熟悉其他语言的泛型,最著名的是C++的模板(templates)。如果这样,你很快就会看到两者的相似之处和重要差异。如果你不熟悉相似的语法结构,那么更好,你可以从头开始而不需要忘记误解。<o:p></o:p>

Generics允许对类型进行抽象(abstract over types)。最常见的例子是集合类型(Container types)Collection的类树中任意一个即是。<o:p></o:p>

下面是那种典型用法:<o:p></o:p>

       List myIntList = new LinkedList();// 1<o:p></o:p>

        myIntList.add(new Integer(0));// 2<o:p></o:p>

       Integer x = (Integer) myIntList.iterator().next();// 3<o:p></o:p>

3行的类型转换有些烦人。通常情况下,程序员知道一个特定的list里边放的是什么类型的数据。但是,这个类型转换是必须的(essential)。编译器只能保证iterator返回的是Object类型。为了保证对Integer类型变量赋值的类型安全,必须进行类型转换。<o:p></o:p>

当然,这个类型转换不仅仅带来了混乱,它还可能产生一个运行时错误(run time error),因为程序员可能会犯错。<o:p></o:p>

程序员如何才能明确表示他们的意图,把一个list中的内容限制为一个特定的数据类型呢?这是generics背后的核心思想。这是上面程序片断的一个泛型版本:<o:p></o:p>

       List<Integer> myIntList = new LinkedList<Integer>(); // 1<o:p></o:p>

       myIntList.add(new Integer(0)); // 2<o:p></o:p>

       Integer x = myIntList.iterator().next(); // 3<o:p></o:p>

注意变量myIntList的类型声明。它指定这不是一个任意的List,而是一个IntegerList,写作:List<Integer>。我们说List是一个带一个类型参数的泛型接口(a generic interface that takes a type parameter),本例中,类型参数是Integer。我们在创建这个List对象的时候也指定了一个类型参数。<o:p></o:p>

另一个需要注意的是第3行没了类型转换。 <o:p></o:p>

现在,你可能认为我们已经成功地去掉了程序里的混乱。我们用第1行的类型参数取代了第3行的类型转换。然而,这里还有个很大的不同。编译器现在能够在编译时检查程序的正确性。当我们说myIntList被声明为List<Integer>类型,这告诉我们无论何时何地使用myIntList变量,编译器保证其中的元素的正确的类型。与之相反,一个类型转换说明程序员认为在那个代码点上它应该是那种类型。<o:p></o:p>

实际结果是,这可以增加可读性和稳定性(robustness),尤其在大型的程序中。<o:p></o:p>

2.            定义简单的泛型<o:p></o:p>

下面是从java.util包中的List接口和Iterator接口的定义中摘录的片断:<o:p></o:p>

public interface List<E> {<o:p></o:p>

           void add(E x);<o:p></o:p>

           Iterator<E> iterator();<o:p></o:p>

}<o:p></o:p>

public interface Iterator<E> {<o:p></o:p>

           E next();<o:p></o:p>

           boolean hasNext();<o:p></o:p>

}<o:p></o:p>

这些都应该是很熟悉的,除了尖括号中的部分,那是接口ListIterator中的形式类型参数的声明(the declarations of the formal type parameters of the interfaces List and Iterator)<o:p></o:p>

类型参数在整个类的声明中可用,几乎是所有可是使用其他普通类型的地方(但是有些重要的限制,请参考第7部分)<o:p></o:p>

(原文:Type parameters can be used throughout the generic declaration, pretty much where you would use ordinary types (though there are some important restrictions; see section 7)<o:p></o:p>

<o:p> </o:p>

在介绍那一节我们看到了对泛型类型声明List(the generic type declaration List)的调用,如List<Integer>。在这个调用中(通常称作一个参数化类型a parameterized type),所有出现形式类型参数(formal type parameter,这里是E)都被替换成实体类型参数(actual type argument)(这里是Integer)<o:p></o:p>

你可能想象,List<Integer>代表一个E被全部替换成Integer的版本:<o:p></o:p>

public interface IntegerList {<o:p></o:p>

void add(Integer x)<o:p></o:p>

Iterator<Integer> iterator();<o:p></o:p>

}<o:p></o:p>

这种直觉可能有帮助,但是也可能导致误解。<o:p></o:p>

它有帮助,因为List<Integer>的声明确实有类似这种替换的方法。<o:p></o:p>

它可能导致误解,因为泛型声明绝不会实际的被这样替换。没有代码的多个拷贝,源码中没有、二进制代码中也没有;磁盘中没有,内存中也没有。如果你是一个C++程序员,你会理解这是和C++模板的很大的区别。<o:p></o:p>

一个泛型类型的声明只被编译一次,并且得到一个class文件,就像普通的class或者interface的声明一样。<o:p></o:p>

类型参数就跟在方法或构造函数中普通的参数一样。就像一个方法有形式参数(formal value parameters)来描述它操作的参数的种类一样,一个泛型声明也有形式类型参数(formal type parameters)。当一个方法被调用,实参(actual arguments)替换形参,方法体被执行。当一个泛型声明被调用,实际类型参数(actual type arguments)取代形式类型参数。<o:p></o:p>

一个命名的习惯:我们推荐你用简练的名字作为形式类型参数的名字(如果可能,单个字符)。最好避免小写字母,这使它和其他的普通的形式参数很容易被区分开来。许多容器类型使用E作为其中元素的类型,就像上面举的例子。在后面的例子中还会有一些其他的命名习惯。<o:p></o:p>

<o:p> </o:p>

3.            泛型和子类继承<o:p></o:p>

让我们测试一下我们对泛型的理解。下面的代码片断合法么?<o:p></o:p>

List<String> ls = new ArrayList<String>(); //1<o:p></o:p>

List<Object> lo = ls; //2 <o:p></o:p>

1行当然合法,但是这个问题的狡猾之处在于第2行。<o:p></o:p>

这产生一个问题:<o:p></o:p>

一个StringList是一个ObjectList么?大多数人的直觉是回答:当然!<o:p></o:p>

好,在看下面的几行:<o:p></o:p>

lo.add(new Object()); // 3<o:p></o:p>

String s = ls.get(0); // 4: 试图把Object赋值给String<o:p></o:p>

这里,我们使用lo指向ls。我们通过lo来访问ls,一个Stringlist。我们可以插入任意对象进去。结果是ls中保存的不再是String。当我们试图从中取出元素的时候,会得到意外的结果。<o:p></o:p>

java编译器当然会阻止这种情况的发生。第2行会导致一个编译错误。<o:p></o:p>

总之,如果FooBar的一个子类型(类或者子接口),而G是某种泛型声明,那么G<Foo>G<Bar>的子类型并不成立!! <o:p></o:p>

这可能是你学习泛型中最难理解的部分,因为它和你的直觉相反。<o:p></o:p>

这种直觉的问题在于它假定这个集合不改变。我们的直觉认为这些东西都不可改变。<o:p></o:p>

举例来说,如果一个交通部(DMV)提供一个驾驶员里表给人口普查局,这似乎很合理。我们想,一个List<Driver>是一个List<Person>,假定DriverPerson的子类型。实际上,我们传递的是一个驾驶员注册的拷贝。然而,人口普查局可能往驾驶员list</

分享到:
评论
1 楼 linginfanta 2007-09-19  
没有翻完。

相关推荐

    JAVA泛型加减乘除

    这是一个使用JAVA实现的泛型编程,分为两部分,第一部分创建泛型类,并实例化泛型对象,得出相加结果。 第二部分用户自行输入0--4,选择要进行的加减乘除运算或退出,再输入要进行运算的两个数,并返回运算结果及...

    Java泛型的用法及T.class的获取过程解析

    Java泛型的用法及T.class的获取过程解析 Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析...

    很好的Java泛型的总结

    Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...

    Java泛型三篇文章,让你彻底理解泛型(super ,extend等区别)

    Java 泛型详解 Java 泛型是 Java SE 5.0 中引入的一项特征,它允许程序员在编译时检查类型安全,从而减少了 runtime 错误的可能性。泛型的主要优点是可以Reusable Code,让程序员编写更加灵活和可维护的代码。 ...

    Java泛型应用实例

    Java泛型是Java编程语言中的一个强大特性,它允许我们在定义类、接口和方法时指定类型参数,从而实现代码的重用和类型安全。在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时...

    1.java泛型定义.zip

    1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....

    java泛型技术之发展

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着Java SE 5.0的发布而引入,极大地增强了代码的类型安全性和重用性。本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展...

    4.java泛型的限制.zip

    4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...

    java 泛型接口示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型接口是泛型在接口中的应用,它允许我们在接口中定义带有类型参数的方法,使得实现该接口的类可以使用不同的数据类型。下面...

    java 泛型方法使用示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型方法是泛型技术在类方法层面的应用,它允许我们定义一个可以处理多种数据类型的通用方法。下面我们将深入探讨Java泛型方法的...

    java 泛型类的类型识别示例

    在Java编程语言中,泛型(Generics)是一种强大的特性,它允许我们在编写代码时指定容器(如集合)可以存储的数据类型。这提高了代码的安全性和效率,因为编译器可以在编译时检查类型,避免了运行时...

    java泛型学习ppt

    "Java 泛型学习" Java 泛型是 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的...

    java泛型的内部原理及更深应用

    Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...

    Java 泛型擦除后的三种补救方法

    Java 泛型是一种强大的工具,它允许我们在编程时指定变量的类型,提供了编译时的类型安全。然而,Java 的泛型在运行时是被擦除的,这意味着在运行时刻,所有的泛型类型信息都会丢失,无法直接用来创建对象或进行类型...

    java泛型详解.pdf

    java泛型详解.pdf

    SUN公司Java泛型编程文档

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入。这个特性极大地提高了代码的类型安全性和可读性,减少了在运行时出现ClassCastException的可能性。SUN公司的Java泛型编程文档,包括...

Global site tag (gtag.js) - Google Analytics