|
楼主 |
发表于 2002-12-27 13:03:55
|
显示全部楼层
这是我在sun上找到的文章关于这个generics的讲解,并作了部分翻译,出错了望更正与讨论
Preparing for Generics
An Introduction
By Paul Mingardi
November 2002
Generics -- also commonly known as parameterized types -- have been used in
other computing languages for years. And now, due to popular demand, generics
is slated to be added to the JavaTM language with the 1.5 release.
Generics – 通常也叫 Parameterized types(参数化类型) – 已经被应用到其它语言一段时
间。 现在,因为广泛需求, generics 已决定加入到java 的1.5版中。
The Problem with Lists
With generics, types that contain data (such as lists) are not defined to operate
over a specific type of data; instead, they operate over a homogeneous set,
where the set type is defined at declaration. How exactly does that help the Java
developer?
通过 generics, 携带数据的类型(如lists) 没有定义通过一个特定的数据类型去操作;它是
通过一个同类集来操作,数据的类型是在声明时给出的。那到底这个性能对java 的开发人员
有什么帮助呢?
The best way to understand what generics can do for you is to study some Java
code that would benefit from generics. The sample below, written to the current
Java language specification, contains a list of String object elements and a list of
Integer object elements (not the primitive type). Because both elements are
subclasses of the Object class, and Java has polymorphic references, you can
apply the list's methods to both objects. Unfortunately, as far as the compiler is
concerned, the elements in both lists are of the type Object, so the only way to
differentiate between the two lists is to use runtime type discrimination on the
elements. Even worse, if a developer confuses the two lists and performs an
illegal cast on an element, the error is not caught until runtime.
学习一些java的代码是理解generics好处的最好方法。 下面的例子,是用现在java语言的
规范写的, 包含一个字符对象列表和一个整型对象列表(不是原始类型). 因为两个元素都是
Object类的子类, java有多态引用,你可以把列表的方法应用到两个对象中去,所以区分两
个列表的唯一方法是靠运行时的类型去区分元素。 更糟糕的是,假如开发者混淆了两个列表,
并且对元素执行了不合法的造型,这个错误只有在运行时才会被发现。
Below are some examples of such errors. In the first example (lines 13 to 20),
you might believe you're working with a list of Integer objects, when in reality it's
a list of Strings. In the second example (lines 11 and 22 to 27), you might think
you're working with a homogenous set of String, but this is a heterogeneous set
of both String and Integer elements. So unless you create a new list subclass for
every element type (which would undermine the advantages of OO reuse),
there's no way to statically constrain the list to a set of homogeneous elements.
And in this simple example, the errors are fairly easy to catch. In a bigger
program, you'd have even bigger problems.
下面是一些类似错误的例子。 在第一个例子(第 13 到 20 行), 你可能相信你在对一个包含整
型对象的列表进行操作, 但事实上它是一个字符型列表。 在第二个对象(行 11 和 22到 27
行), 你可能想你在对字符的同类集在进行操作,但它却是一个既有字符型也有整型的不同类
集。所以除非你自己去为每一个元素类型建一个新的列表子类(这会破坏面向对象重用的优
势),没有任何方法静止地强制列表的元素为同类集。 在这个简单的例子中,错误是容易被捕
获的,但在大一点的程序里时,你会遇到更大的问题。
1..
2. List stringList = new LinkedList();
3. List integerList = new LinkedList();
4.
5. integerList.add(new Integer(1));
6. integerList.add(new Integer(2));
7.
8. stringList.add(new String("I am a String"));
9.
10. // Nothing constrains the elements to a homogeneous set.
11. stringList.add(new Integer(1));
12.
13. Iterator listIterator = integerList.iterator();
14.
15. // Compiler unaware of the list's return type and the illegal
cast.
16. // Developer meant to iterate through the string list.
17. while(listIterator.hasNext()) {
18.
19. // Illegal cast caught at runtime.
20. String item = (String)listIterator.next();
21. }
22.
23. listIterator = stringList.iterator();
24. // No guarantee of homogeneous containers.
25. while (listIterator.hasNext()) {
26. // fail at runtime due to heterogeneous set
27. String item = (String)listIterator.next();
28. }
29..
The Generics Advantage
Generics优势
With generics, you achieve polymorphic behavior similar to the example above,
but with strong static type-checking; the compiler knows that the two lists are
different because they contain different elements, and these lists are guaranteed
to contain only a homogeneous set of elements. The sample code below is a
translation of the previous example, using generics this time. As you can see
from comments in the code, all the errors are caught at compile time. Don't
worry about the syntax for now -- we'll cover that shortly.
使用generic, 你要完成多态行为就像上面的例子, 但有了更强的静态类型检测;编译器知道
两个列表是不同的,因为它们包含不同类型的元素,并且这些列表保证只包含同类集的元素。
下面的示例代码是前一个例子使用Generics技术实现的转换. 正如你在代码注释中看到的,
所在错误都在编译时已发现。现在先不要担心句法的使用—我们将会很快讲到。
In comparing the two examples, you should notice that additional type
information is included in the generics code, which directs the compiler as to what
type each container should contain.
比较这两个例子,你会发现一些附加的类型信息包含在 generics的代码中, 这样就告诉了编
译器包容器中应包含什么类型。
1..
2. import java.util.LinkedList;
3. import java.util.Collections;
4. import java.util.Iterator;
5.
6. public class genericsExample2{
7.
8. static public void main(String[] args) {
9. LinkedList<String> stringList = new LinkedList<String>();
10. LinkedList<Integer> integerList = new
LinkedList<Integer>();
11.
12. integerList.add(new Integer(1));
13. integerList.add(new Integer(2));
14.
15. stringList.add(new String("I am a String"));
16. stringList.add(new Integer(1)); // causes a compilation
error
17.
18. /* genericsExample2.java:16: cannot resolve symbol
19. ** symbol : method add (java.lang.Integer)
20. */
21.
22. Iterator<Integer> listIterator = integerList.iterator();
23. String item;
24. while(listIterator.hasNext()) {
25. item = listIterator.next(); // causes a compilation
error
26.
27. /* genericsExample2.java:25: incompatible types
28. ** found : java.lang.Integer
29. ** required: java.lang.String
30. */
31. }
32.
33. listIterator = stringList.iterator(); // causes a
compilation error
34.
35. /* genericsExample2.java:33: incompatible types
36. ** found : java.util.Iterator<java.lang.String>
37. ** required: java.util.Iterator<java.lang.Integer>
38. */
39. // the iterator is guaranteed to be homogeneous
40. while (listIterator.hasNext()) {
41. item = listIterator.next();
42.
43. /* genericsEx2.java:41: incompatible types
44. ** found : java.lang.Integer
45. ** required: java.lang.String
46. */
47. }
48. } // main
49. } // class genericsExample2
With these examples, you can understand why generics is among the most-
requested additions to the Java language. Here are a few of the benefits:
通过这个例子,你会明白为何generics是最多人要求为java语言增加的功能之一。这里时一
些好处:
? The flexibility of dynamic binding, with the advantage of static type-
checking. Compiler-detected errors are less expensive to repair than those
detected at runtime.
方便的动态绑定伴随着静态类型检测。编译器检测错误比在运行期间修改这些错误要
便宜。
? There is less ambiguity between containers, so code reviews are simpler.
容器间更清淅,所以在检视代码时更简单。
? Using fewer casts makes code cleaner.
使用较少的造型,令代码更整洁.
Basic Syntax Overview
So far, you've only seen the genericized container classes provided to us. But you
can also declare your own generic interfaces, classes, and methods. The following
table illustrates the syntax you would use.
Syntax
Paramaterized
Type
Vector<String> stringVector = new Vector<String>
List<Integer> integerList = new List<Integer>
Interface
interface List<Element> implements MyInterface{...}
Class
class MyList<Element> {...}
class MyList<Element> implements List<Element> {...}
Method
boolean containsBoth(Element a, Element b);
static <Element> boolean swap(List<Element> list, int i,
int j);
The following example uses similar syntax in code: MyInterface
Getting Started with Generics
For more information on generics, you can refer to the specification and to the
JSR 14. Developers can start writing generics code today using a prototype
implementation of the Java compiler, which supports generics (as described in the
draft specification). The prototype includes: the source written in the extended
language, a jar file containing the class files for running and bootstrapping the
compiler, and a jar file containing stubs for the collection classes. It also includes
a Java source example and a helpful makefile that compiles the source and
invokes the Java Virtual Machine (JVM). Here are the steps to get started using C-
shell.
1. Download the generics prototype archive file
If you are not already a member of the Java Developer Connection, you
will need to register.
Unzip the archive into the installation directory /install_dir
- unzip adding_generics-1_3-ea.zip
2. Download and install JDKTM 1.4.1
3. Set the environment variables
setenv JSR14DISTR /install_dir/jsr14_adding_generics-1_3-ea
setenv J2SE14 /jdk_install_dir
4. Run the examples
cd /install_dir/jsr14_adding_generics-1_3-ea/examples
Compile and run the Test.java sample using the makefile.
- make
See Also
? Early Access Prototype for JSR-14
? JSR 14 Specification
About the Author
Paul Mingardi is a Market Development Engineer at Sun Microsystems, working on
technology adoption for partners in health care, banking, and finance. He also
works with independent software vendors, to help them become successful using
Java and other Sun technologies. Paul is a Sun Certified Enterprise Architect and
holds a total of seven certifications. |
|