Documentation

The Java™ Tutorials
Hide TOC
Defining Simple Generics定义简单泛型
Trail: Bonus
Lesson: Generics

Defining Simple Generics定义简单泛型

Here is a small excerpt from the definitions of the interfaces List and Iterator in package java.util:下面是java.util包中接口ListIterator定义的一个小摘录:

public interface List <E> {
void add(E x);
    Iterator<E> iterator();
}
public interface Iterator<E> {
    E next();
boolean hasNext();
}

This code should all be familiar, except for the stuff in angle brackets. 这段代码应该大家都很熟悉,除了尖括号中的内容。Those are the declarations of the formal type parameters of the interfaces List and Iterator.这些是接口ListIterator形式类型参数的声明。

Type parameters can be used throughout the generic declaration, pretty much where you would use ordinary types (though there are some important restrictions; see the section The Fine Print.类型参数可以在整个泛型声明中使用,与使用普通类型的地方差不多(尽管有一些重要的限制;请参阅细节一节)。

In the introduction, we saw invocations of the generic type declaration List, such as List<Integer>. 在简介中,我们看到了泛型类型声明List的调用,比如List<Integer>In the invocation (usually called a parameterized type), all occurrences of the formal type parameter (E in this case) are replaced by the actual type argument (in this case, Integer).在调用中(通常称为参数化类型),所有出现的形式类型参数(本例中为E)都被实际的类型参数(本例中为Integer)替换。

You might imagine that List<Integer> stands for a version of List where E has been uniformly replaced by Integer:你可能会想象,List<Integer>代表List的一个版本,其中EInteger一致性替换:

public interface IntegerList {
void add(Integer x);
    Iterator<Integer> iterator();
}

This intuition can be helpful, but it's also misleading.这种直觉可能有帮助,但也有误导性。

It is helpful, because the parameterized type List<Integer> does indeed have methods that look just like this expansion.这很有帮助,因为参数化类型List<Integer>确实有类似于此扩展的方法。

It is misleading, because the declaration of a generic is never actually expanded in this way. 这是误导性的,因为泛型的声明实际上从未以这种方式展开。There aren't multiple copies of the code—not in source, not in binary, not on disk and not in memory. 代码没有多个副本—不在源代码中,不在二进制文件中,不在磁盘上,也不在内存中。If you are a C++ programmer, you'll understand that this is very different than a C++ template.如果你是C++程序员,你会明白这与C++模板非常不同。

A generic type declaration is compiled once and for all, and turned into a single class file, just like an ordinary class or interface declaration.泛型类型声明将一次性编译,并转换为单个类文件,就像普通类或接口声明一样。

Type parameters are analogous to the ordinary parameters used in methods or constructors. 类型参数类似于方法或构造函数中使用的普通参数。Much like a method has formal value parameters that describe the kinds of values it operates on, a generic declaration has formal type parameters. 与方法具有描述其操作的值类型的形式值参数类似,泛型声明也具有形式类型参数。When a method is invoked, actual arguments are substituted for the formal parameters, and the method body is evaluated. 当调用一个方法时,用实际参数代替形式参数,并对方法体进行求值。When a generic declaration is invoked, the actual type arguments are substituted for the formal type parameters.调用泛型声明时,实际的类型参数将替换为形式类型参数。

A note on naming conventions. 关于命名约定的说明。We recommend that you use pithy (single character if possible) yet evocative names for formal type parameters. 我们建议对正式类型参数使用简洁(如果可能的话,使用单个字符)但又能引起共鸣的名称。It's best to avoid lower case characters in those names, making it easy to distinguish formal type parameters from ordinary classes and interfaces. 最好避免在这些名称中使用小写字符,这样就可以很容易地将形式类型参数与普通类和接口区分开来。Many container types use E, for element, as in the examples above. 许多容器类型使用E表示元素,如上面的示例所示。We'll see some additional conventions in later examples.我们将在后面的示例中看到一些附加约定。


Previous page: Introduction
Next page: Generics and Subtyping