effective-Java/ch05泛型/27.消除非检查警告.md
2019-11-21 19:59:07 +08:00

43 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 消除非检查警告
使用泛型编程时,会看到许多编译器警告:
- 未经检查的强制转换警告
- 未经检查的方法调用警告
- 未经检查的参数化可变长度类型警告
- 未经检查的转换警告
你使用泛型获得的经验越多,获得的警告越少,但不要期望新编写的代码能够干净地编译。
**示例代码**[Item27Example01.java](Generics/src/main/java/com/jueee/item27/Item27Example01.java)
```java
// 警告HashSet是原始类型。 泛型类型HashSet <E>的引用应参数化。
new HashSet();
// 进行指示修正,让警告消失。
// 请注意,实际上并不需要指定类型参数,只是为了表明它与 Java 7 中引入的钻石运算符(「<>」)一同出现。
new HashSet<>();
```
但一些警告更难以消除。 本章充满了这种警告的例子。 当你收到需要进一步思考的警告时,坚持不懈! **尽可能地消除每一个未经检查的警告。** 如果你消除所有的警告,你可以放心,你的代码是类型安全的,这是一件非常好的事情。 这意味着在运行时你将不会得到一个 `ClassCastException` 异常,并且增加了你的程序将按照你的意图行事的信心。
**如果你不能消除警告,但你可以证明引发警告的代码是类型安全的,那么(并且只能这样)用 @SuppressWarnings("unchecked") 注解来抑制警告。** 如果你在没有首先证明代码是类型安全的情况下压制警告,那么你给自己一个错误的安全感。 代码可能会在不发出任何警告的情况下进行编译,但是它仍然可以在运行时抛出 `ClassCastException` 异常。 但是,如果你忽略了你认为是安全的未经检查的警告(而不是抑制它们),那么当一个新的警告出现时,你将不会注意到这是一个真正的问题。 新出现的警告就会淹没在所有的错误警告当中。
`SuppressWarnings` 注解可用于任何声明,从单个局部变量声明到整个类。 始终在尽可能最小的范围内使用 `SuppressWarnings` 注解。 通常这是一个变量声明或一个非常短的方法或构造方法。 切勿在整个类上使用 `SuppressWarnings` 注解。 这样做可能会掩盖重要的警告。
如果你发现自己在长度超过一行的方法或构造方法上使用 `SuppressWarnings` 注解,则可以将其移到局部变量声明上。 你可能需要声明一个新的局部变量,但这是值得的。
```java
// 使用 SuppressWarnings 注解声明单个局部变量
@SuppressWarnings({"rawtypes", "unchecked"})
Set<String> set = new HashSet();
```
**示例代码**[Item27Example02.java](Generics/src/main/java/com/jueee/item27/Item27Example02.java):最小化未经检查的警告被抑制的范围。
未经检查的警告是重要的。 不要忽视他们。
每个未经检查的警告代表在运行时出现 `ClassCastException` 异常的可能性。 尽你所能消除这些警告。
如果无法消除未经检查的警告,并且可以证明引发该警告的代码是安全类型的,则可以在尽可能小的范围内使用 `@SuppressWarnings(“unchecked”)` 注解来禁止警告。 记录你决定在注释中抑制此警告的理由。