您的位置:首页 > 编程语言 > Java开发

有用但多疑的十大Java编程技术

2015-09-09 15:02 253 查看
在编码过一段时间后(哎呀,拿我来说,已经20多年了,当你乐享其中时,时间过得飞快),有人已经开始拥抱他们的习惯了。

因为,你知道…

“会出错的事情总会出错”– 墨菲定律

这就是人们拥抱“自卫编程”,也就是多疑的习惯,有时有道理,有时更模糊。可能有一点奇怪当你想到一个人写这个的时候。

下面是我总结的10大有用但多疑的Java编程技术。开始吧:

1.优先放置字符常量

把String变量放在equals()方法的左边,对于预防偶然出现的空指针异常来说,从不是一个好主意。

// 错误
if (variable.equals("literal")) { ... }

// 正确
if ("literal".equals(variable)) { ... }


这再明显不过了,把变量放在右边是更好的版本。

2.不要相信早期的JDK APIs

在Java的早期时代,编程肯定很痛苦。APIs是非常不成熟的,你可能遇到过下面这样的代码:

String[] files = file.list();

// 小心
if (files != null) {
for (int i = 0; i < files.length; i++) {
...
}
}


多疑了?可能吧,但是看看Javadoc:

“如果抽象的pathname没有指定一个目录,那么这个方法会返回null。否则会返回string数组,数组中的每一个string都是该目录下的文件或目录。

对了。最好再添加一个检查,只是为了确保安全起见。

if (file.isDirectory()) {
String[] files = file.list(); // 小心 if (files != null) { for (int i = 0; i < files.length; i++) { ... } }
}


3.不要相信“-1”

我知道这是多疑的。Javadoc中的 String.indexOf()方法是这样声明的:

“返回指定字符在字符序列中的第一次出现的位置,如果没有该字符,返回-1”

所以,-1就能打保票了吗?不能,考虑下面情况:

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

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


谁知道呢。可能在某些情况下他们还需要继续编码呢。另一个字符串可能包含是否检查大小写,空串(返回0),空值(异常)等情况,

这些都可能是一个返回-2的好例子,谁知道呢。

毕竟,我们讨论过无数次关于null的问题。为什么我们不开始讨论-1呢?在某种程度上,null也是基本数据类型的可选值吗?

4.避免意外赋值

假定下面是JavaScript,但是也让我们对这种语言多疑。

// 糟糕
if (variable = 5) { ... }

// 好点 (因为会引发一个错误)
if (5 = variable) { ... }

// 故意 (记住. 多疑的JavaScript: ===)
if (5 === variable) { ... }


再一次,如果你的等式中有常量,把它放到左边。如果你没把另一个=号加下,在这里你就可能意外的犯错。

5.检查null和length

无论什么时候遇到一个集合,数组等类型,确保它是存在且非空的。

// 错误
if (array.length > 0) { ... }

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


你永远不知道这些数组来自哪里。可能来自早期的Java APIs。

6.所有的方法都是final的

你能告诉我所有你想要的开闭原则,那是胡说。我不相信你(正确的继承了我的类)并且我不相信我自己(没有意外继承我的类)。

这就是为什么没有显式的使用子类型的方法都是final的。

// 错误
public void boom() { ... }

// 正确,不能更改。
public final void dontTouch() { ... }


是的,这个方法是final的。如果这对你不起作用的话,修补它或重写字节码。或者发送一个特性请求。

尽管我确定你想要重写的意图不是一个好主意。

7.所有的变量和参数是final的

正如我刚才说到的,我不相自己。(不会意外的重写我的值)。既然都这么说了,我完全不相信我自己了。因为…



这也是为什么所有的变量和参数都要做成final的原因。

// 错误
void input(String importantMessage) {
String answer = "...";

answer = importantMessage = "LOL accident";
}

// 正确
final void input(final String importantMessage) {
final String answer = "...";
}


好,我承认。这个我没有经常应用在实际中,尽管,我真的应该使用。

8.重载时不要相信范型

// 错误
<T> void bad(T value) {
bad(Collections.singletonList(value));
}

<T> void bad(List<T> values) {
...
}

// 正确
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) {
...
}


因为,你的用户,他们会像这样使用:

// 这个类库真烂
@SuppressWarnings("all")
Object t = (Object) (List) Arrays.asList("abc");
bad(t);


相信我。我看见过这种情况。包括像下面这样的:



还是多疑点好。

9.在switch上永远抛出默认值

// 错误
switch (value) {
case 1: foo(); break;
case 2: bar(); break;
}

// 正确
switch (value) {
case 1: foo(); break;
case 2: bar(); break;
default:
throw new ThreadDeath("That'll teach them");
}


因为当value==3的那一刻,肯定会发生错误。不要说枚举,因为枚举也会发生这种情况。

10.switch要用大括号

事实上,对于那些喝醉了或打赌输了的人来说,switch是最邪恶的声明了。参考下面例子:

// 错误,不编译
switch (value) {
case 1: int j = 1; break;
case 2: int j = 2; break;
}

// 正确
switch (value) {
case 1: {
final int j = 1;
break;
}
case 2: {
final int j = 2;
break;
}

// 记住
default:
throw new ThreadDeath("That'll teach them");
}


在switch声明内,在所有的case声明中只有一个范围定义。事实上,这些case声明甚至不是真正的声明,它们更像是switch要被调用时的标签。

总结

多疑编程有时看起来有点奇怪,当经常这样编码时结果就是比实际需要的有一点冗余。你可能认为,“这种情况永远不可能发生”,但正如我之前所说的。在经过20左右的编程后,你只是不想再修复那些愚蠢且没必要存在的小错误,而只是因为古老有缺陷的语言造成的。

因为你懂的…

现在,轮到你了!

你在编程中最多疑的怪癖是什么?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: