6. 所有的方法都用 final 声明
  你可以告诉我任何你想要的开闭原则,不过那都是胡说八道。我不相信你(可以正确继承我的类),也不相信我自己(不会意外地继承我的类)。因此除了接口(专门用于继承)都应该是严格的 final。可以查看我们的 Java 编码中 10 个微妙的佳实践 中的#9。
  // Bad
  public void boom() { ... }
  // Good. Don't touch.
  public final void dontTouch() { ... }
  是的,写成final。如果这样做对你来说没有意义,你也可以通过修改或重写字节码来改变类和方法,或者发送功能请求。我敢肯定重写类/方法并不是一个好主意。
  7. 所有的变量和参数都用 final 声明
  像我说的。我不相信自己不会无意间重写了某个值。这么说来,我的确一点都不相信自己。因为:
  这也是为什么所有的变量和参数都用final声明的原因。
  // Bad
  void input(String importantMessage) {
  String answer = "...";
  answer = importantMessage = "LOL accident";
  }
  // Good
  final void input(final String importantMessage) {
  final String answer = "...";
  }
  好吧,我承认,这一条我自己也不常用,虽然我应该用。我希望Java能像Scala语言一样,人们在所有地方都直接用 val 来表示变量,甚至都不考虑易变性,除非明确需要的时候他们才用 var 来声明变量,但是这样的机会特别少。
  8. 重载的时候不要相信泛型
  是的,这是会发生的。你觉得你写了一个超好的API,它真的是既酷炫又直观;接着出现了一群用户,他们只是把一切类型生搬硬套进 Object 中 直到那该死的编译器停止工作,然后他们突然链接到了错误的方法,认为这一切都是你的错(事情总是这样)。
  思考一下这个:
// Bad
<T> void bad(T value) {
bad(Collections.singletonList(value));
}
<T> void bad(List<T> values) {
...
}
// Good
final <T> void good(final T value) {
if (value instanceof List)
good((List<?>) value);
else
good(Collections.singletonList(value));
}
final <T> void good(final List<T> values) {
...
}
  因为,你知道的…你的用户们,他们像这样
  // This library sucks
  @SuppressWarnings("all")
  Object t = (Object) (List) Arrays.asList("abc");
  bad(t);
  相信我,我看过的多了,还有这样的
  所以说偏执是有好处的。
  9. 总是在switch语句里加上default
  Switch…作为滑稽的表达式之一,我不知道是该心存敬畏还是默默哭泣。不管怎样,我们既然无法摆脱 switch ,在必要的时候我们好能够正确使用它,例如:
  // Bad
  switch (value) {
  case 1: foo(); break;
  case 2: bar(); break;
  }
  // Good
  switch (value) {
  case 1: foo(); break;
  case 2: bar(); break;
  default:
  throw new ThreadDeath("That'll teach them");
  }
  因为在当 value=3 被引入到软件中的时候,default 能发挥作用,使其正常运行!别和我提 enum 类型,因为这对 enums 也一样适用。
  10. 用大括号隔开 switch 的每一个 case 块
  事实上,switch是坑爹的语句,任何喝醉了或是赌输了的人都可以在某种语言中使用它。看看下面这个例子:
  // Bad, doesn't compile
  switch (value) {
  case 1: int j = 1; break;
  case 2: int j = 2; break;
  }
  // Good
  switch (value) {
  case 1: {
  final int j = 1;
  break;
  }
  case 2: {
  final int j = 2;
  break;
  }
  // Remember:
  default:
  throw new ThreadDeath("That'll teach them");
  }
  在switch语句中,为所有的case都只定义了一个作用域。事实上,这些case不是真正意义上的语句,他们更像是标签,而switch是指向这些标签的goto语句。事实上,你甚至可以把case语句和 惊人的FORTRAN77项声明 类比,对于FORTRAN,它的神秘已经超越了它的功能。
  这意味着变量final int j 可以被任何case访问,不论我们是否有break。看起来并不是很直观。我们可以通过添加简单的花括号为每一个case创建一个新的嵌套的作用域,当然不要忘了在每个 case 的语句块后加 break。
  结论
  编程时的强迫症有时候看起来会很奇怪,会使得代码往往比必需的还要冗长。你可能会想,“啊,这种情况永远不会发生!”,但是正如我所说的,在经历了20年左右的编程生涯后,你不会想要再去修正那些只是因为编程语言的古老和固有缺陷而导致的愚蠢而不必要的bug了。因为你知道…..