偏执却管用的 10 条 Java 编程技巧

(转载:https://mp.weixin.qq.com/s/_Eall34E45WHkty8oUcq9Q)

1. 把字符串常量放在前面

通过把字符串常量放在比较函数equals()比较项的左侧来防止偶然的 NullPointerException 从来都不是一个坏主意,就像这样:

// Bad

if (variable.equals("literal")) { ... }

// Good

if ("literal".equals(variable)) { ... }

这是毫无疑问的,把一种表达式转换成另一种更好的表达式,并不会失去什么。只要我们的Options是真实存在的(Java 8中 Optional是对可以为空的对象进行的封装),不是吗?讨论一下…

3. 不要相信“-1”

我知道这很偏执,Javadoc中关于 String.indexOf() 的早期描述是这样的…

“字符在字符序列中第一次出现的位置将作为结果[被返回],如果字符不存在则返回-1。”

所以,-1 就可以理所当然被拿来用,对吗?我说不对,看看这个:

// Bad

if (string.indexOf(character) != -1) { ... }

// Good

if (string.indexOf(character) >= 0) { ... }

谁知道呢。也许在某个特定场合下他们将会需要另一种 编码值,如果不区分大小写的话,otherString 就会被包含进去…此时或许可以返回 -2呢?谁知道呢。

 4. 避免意外的赋值

// Ooops

if (variable = 5) { ... }

// Better (because causes an error)

if (5 = variable) { ... }

// Intent (remember. Paranoid JavaScript: ===)

if (5 === variable) { ... }

再说一遍。如果你的表达式中有常量,将它放在等式左边。这样当你打算再添加一个 = 时,不容易出错

5. 检查null和长度

不管什么时候你有一个集合、数组或者其他的,确保它存在并且不为空。

// Bad

if (array.length > 0) { ... } 

// Good

if (array != null && array.length > 0) { ... }

你不知道这些数组来自哪儿,也许是早期的JDK API呢?

6. 所有的方法都用 final 声明

你可以告诉我任何你想要的开闭原则,不过那都是胡说八道。我不相信你(可以正确继承我的类),也不相信我自己(不会意外地继承我的类)。因此除了接口(专门用于继承)都应该是严格的 final。可以查看我们的 Java 编码中 10 个微妙的最佳实践 中的#9。

 

// Bad

public void boom() { ... }

 

// Good. Don't touch.

public final void dontTouch() { ... } 

是的,写成final。如果这样做对你来说没有意义,你也可以通过修改或重写字节码来改变类和方法,或者发送功能请求。我敢肯定重写类/方法并不是一个好主意

7. 所有的变量和参数都用 final 声明

// Bad

void input(String importantMessage) {

    String answer = "...";

 

    answer = importantMessage = "LOL accident";

}

 

// Good

final void input(final String importantMessage) {

    final String answer = "...";

}

8. 重载的时候不要相信泛型

思考一下这个:

 

// 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) {

    ...

}

 9. 总是在switch语句里加上default

// 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");

}

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");

}

posted @ 2018-02-22 21:58  刘大飞  阅读(109)  评论(0编辑  收藏  举报