The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
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
. ls
和lo
加了别名。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 String
s 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>
. Foo
是Bar
的子类型(子类或子接口),而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>
,假设Driver
是Person
的一个子类型。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.到目前为止,我们看到的规则是相当严格的。