From 19760c32c1568ec88b9b17c18be94d91cf171e08 Mon Sep 17 00:00:00 2001 From: FengBaoheng <344092466@qq.com> Date: Mon, 13 Apr 2020 10:18:58 +0800 Subject: [PATCH] fix typos on 20-Generics (#430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix typo 本章小节->本章小结 * fix typos on 20-Generics 修正20章的打字错误 --- docs/book/20-Generics.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/book/20-Generics.md b/docs/book/20-Generics.md index 4a0a0ad..e207114 100644 --- a/docs/book/20-Generics.md +++ b/docs/book/20-Generics.md @@ -1292,6 +1292,7 @@ public class LostInformation { [K,V] [Q] [POSITION,MOMENTUM] +*/ ``` 根据 JDK 文档,**Class.getTypeParameters()** “返回一个 **TypeVariable** 对象数组,表示泛型声明中声明的类型参数...” 这暗示你可以发现这些参数类型。但是正如上例中输出所示,你只能看到用作参数占位符的标识符,这并非有用的信息。 @@ -1616,6 +1617,7 @@ public class FilledList extends ArrayList { /* Output: [Hello,Hello,Hello,Hello] [47,47,47,47] +*/ ``` 即使编译器无法得知 `add()` 中的 **T** 的任何信息,但它仍可以在编译期确保你放入 **FilledList** 中的对象是 **T** 类型。因此,即使擦除移除了方法或类中的实际类型的信息,编译器仍可以确保方法或类中使用的类型的内部一致性。 @@ -2636,7 +2638,7 @@ public class NonCovariantGenerics { } ``` -尽管你在首次阅读这段代码时会认为“不能将一个 **Apple** 集合赋值给一个 **Fruit** 集合”。记住,泛型不仅仅是关于集合,它真正要表达的是“不能把一个涉及 **Apple** 的泛型赋值给一个涉及 **Fruit** 的泛型”。如果像在数组中的情况一样,编译器对代码的了解足够多,可以确定所涉及到的集合,那么它可能会留下一些余地。但是它不知道任何有关这方面的信息,因此它拒绝向上转型。然而实际上这也不是向上转型—— **Apple** 的 **List** 不是 **Fruit** 的 **List**。**Apple** 的 **List** 将持有 **Apple** 和 **Apple** 的子类型,**Fruit** 的 **List** 将持有任何类型的 **Fruit**。是的,这包括 **Apple**,但是它不是一个 **Apple** 的 **List**,它仍然是 **Fruit** 的 **List**。**Apple** 的 **List** 在类型上不等价于 **Fruit** 的 **List**,即使 **Apple** 是一种 **Fruit** 类型。 +尽管你在首次阅读这段代码时会认为“不能将一个 **Apple** 集合赋值给一个 **Fruit** 集合”。记住,泛型不仅仅是关于集合,它真正要表达的是“不能把一个涉及 **Apple** 的泛型赋值给一个涉及 **Fruit** 的泛型”。如果像在数组中的情况一样,编译器对代码的了解足够多,可以确定所涉及到的集合,那么它可能会留下一些余地。但是它不知道任何有关这方面的信息,因此它拒绝向上转型。然而实际上这也不是向上转型—— **Apple** 的 **List** 不是 **Fruit** 的 **List**。**Apple** 的 **List** 将持有 **Apple** 和 **Apple** 的子类型,**Fruit** 的 **List** 将持有任何类型的 **Fruit**。是的,这包括 **Apple**,但是它不是一个 **Apple** 的 **List**,它仍然是 **Fruit** 的 **List**。**Apple** 的 **List** 在类型上不等价于 **Fruit** 的 **List**,即使 **Apple** 是一种 **Fruit** 类型。 真正的问题是我们在讨论的集合类型,而不是集合持有对象的类型。与数组不同,泛型没有内建的协变类型。这是因为数组是完全在语言中定义的,因此可以具有编译期和运行时的内建检查,但是在使用泛型时,编译器和运行时系统不知道你想用类型做什么,以及应该采用什么规则。 @@ -2736,7 +2738,7 @@ public class Holder { Holder apple = new Holder<>(new Apple()); Apple d = apple.get(); apple.set(d); -// Holder fruit = apple; // Cannot upcast + // Holder fruit = apple; // Cannot upcast Holder fruit = apple; // OK Fruit p = fruit.get(); d = (Apple) fruit.get(); @@ -2745,8 +2747,8 @@ public class Holder { } catch (Exception e) { System.out.println(e); } -// fruit.set(new Apple()); // Cannot call set() -// fruit.set(new Fruit()); // Cannot call set() + // fruit.set(new Apple()); // Cannot call set() + // fruit.set(new Fruit()); // Cannot call set() System.out.println(fruit.equals(d)); // OK } } @@ -3325,7 +3327,7 @@ Double ``` `f1()` 中的类型参数都是确切的,没有通配符或边界。在 `f2()` 中,**Holder** 参数是一个无界通配符,因此它看起来是未知的。但是,在 `f2()` 中调用了 `f1()`,而 `f1()` 需要一个已知参数。这里所发生的是:在调用 `f2()` 的过程中捕获了参数类型,并在调用 `f1()` 时使用了这种类型。 -你可能想知道这项技术是否可以用于写入,但是这要求在传递 `Holder` 时同时传递一个具体类型。捕获转换只有在这样的情况下可以工作:即在方法内部,你需要使用确切的类型。注意,不能从 `f2()` 中返回 **T**,因为 **T ** 对于 `f2()` 来说是未知的。捕获转换十分有趣,但是非常受限。 +你可能想知道这项技术是否可以用于写入,但是这要求在传递 `Holder` 时同时传递一个具体类型。捕获转换只有在这样的情况下可以工作:即在方法内部,你需要使用确切的类型。注意,不能从 `f2()` 中返回 **T**,因为 **T** 对于 `f2()` 来说是未知的。捕获转换十分有趣,但是非常受限。