Documentation

The Java™ Tutorials
Hide TOC
Generics and Subtyping泛型和子类型
Trail: Bonus
Lesson: Generics

Generics and Subtyping泛型和亚型

Let's test your understanding of generics. Is the following code snippet legal?让我们测试一下你对泛型的理解。以下代码片段合法吗?

List<String> ls = new ArrayList<String>(); // 1
List<Object> lo = ls; // 2

Line 1 is certainly legal. 第一行当然是合法的。The trickier part of the question is line 2. 问题中更棘手的部分是第二行。This boils down to the question: is a List of String a List of Object. 这归结为一个问题:String列表是Object列表吗。Most people instinctively answer, "Sure!"大多数人本能地回答:“当然!”

Well, take a look at the next few lines:好吧,看看下面几行:

lo.add(new Object()); // 3
String s = ls.get(0); // 4: Attempts to assign an Object to a String!

Here we've aliased ls and lo. 这里我们给lslo加了别名。Accessing ls, a list of String, through the alias lo, we can insert arbitrary objects into it. 通过别名lo访问字符串列表ls,我们可以在其中插入任意对象。As a result ls does not hold just Strings anymore, and when we try and get something out of it, we get a rude surprise.因此,ls不再只是一个String,当我们试图从中获得一些东西时,我们会得到一个粗鲁的惊喜。

The Java compiler will prevent this from happening of course. Java编译器当然会阻止这种情况发生。Line 2 will cause a compile time error.第2行将导致编译时错误。

In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>. 一般来说,如果FooBar的子类型(子类或子接口),而G是某种泛型类型声明,那么G<Foo>不是G<Bar>的子类型。This is probably the hardest thing you need to learn about generics, because it goes against our deeply held intuitions.关于泛型,这可能是你需要了解的最难的事情,因为它违背了我们根深蒂固的直觉。

We should not assume that collections don't change. 我们不应该假设集合不会改变。Our instinct may lead us to think of these things as immutable.本能可能会让我们认为这些东西是不变的。

For example, if the department of motor vehicles supplies a list of drivers to the census bureau, this seems reasonable. 例如,如果机动车辆部向人口普查局提供一份司机名单,这似乎是合理的。We think that a List<Driver> is a List<Person>, assuming that Driver is a subtype of Person. 我们认为List<Driver>就是List<Person>,假设DriverPerson的一个子类型。In fact, what is being passed is a copy of the registry of drivers. 事实上,正在通过的是司机登记册的副本。Otherwise, the census bureau could add new people who are not drivers into the list, corrupting the DMV's records.否则,人口普查局可能会将非司机的新人加入名单,从而破坏DMV的记录。

To cope with this sort of situation, it's useful to consider more flexible generic types. 为了应对这种情况,考虑更灵活的泛型类型是有用的。The rules we've seen so far are quite restrictive.到目前为止,我们看到的规则是相当严格的。


Previous page: Defining Simple Generics
Next page: Wildcards