[首页]
[文章]
[教程]
首页
Web开发
Windows开发
编程语言
数据库技术
移动平台
系统服务
微信
设计
布布扣
其他
数据分析
首页
>
编程语言
> 详细
[Java]剑走偏锋的10条编程技巧
时间:
2015-10-19 14:02:39
阅读:
249
评论:
0
收藏:
0
[点我收藏+]
“
任何可能出错的事情,最后都会出错。
”
这就是人们为什么喜欢进行“防错性程序设计”的原因。偏执的习惯有时很有意义,有时则不够清晰也不够聪明,也许当你想到这样写的人的时候还会觉得有点怪异。下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看:
1.把字符串常量放在前面
通过把字符串常量放在比较函数equals()比较项的左侧来防止偶然的 NullPointerException 从来都不是一个坏主意,就像这样:
Java代码
// Bad
if
(variable.equals(
"literal"
)) { ... }
// Good
if
(
"literal"
.equals(variable)) { ... }
这是毫无疑问的,把一种表达式转换成另一种更好的表达式,并不会失去什么。只要我们的Options是真实存在的(Java 8中 Optional是对可以为空的对象进行的封装),不是吗?讨论一下…
2.不要相信早期的JDK APIs
Java刚出现的时候,编程一定是件很痛苦的事。那时的API仍然不够成熟,你可能曾经遇到过这样一段代码:
Java代码
String[] files = file.list();
// Watch out
if
(files !=
null
) {
for
(
int
i =
0
; i < files.length; i++) {
...
}
}
看起来很奇怪对吗?也许吧,
但是看看这个Javadoc
:
“如果抽象路径名表示的不是一个目录,那么这个方法返回null。否则返回一个字符串数组,其中每个字符串表示当前目录下的一个文件或目录。”
是的,最好再加上判空检查,以确保正确:
Java代码
if
(file.isDirectory()) {
String[] files = file.list();
// Watch out
if
(files !=
null
) {
for
(
int
i =
0
; i < files.length; i++) {
...
}
}
}
糟糕!前者违反了
Java编码中10个微妙的最佳实践
的规则#5和#6。因此一定要记得判 null检查!
3. 不要相信“-1”
我知道这很偏执,Javadoc中关于 String.indexOf() 的早期描述是这样的…
“字符在字符序列中第一次出现的位置将作为结果[被返回],如果字符不存在则返回-1。”
所以,-1 就可以理所当然被拿来用,对吗?我说不对,看看这个:
Java代码
// Bad
if
(string.indexOf(character) != -
1
) { ... }
// Good
if
(string.indexOf(character) >=
0
) { ... }
谁知道呢。也许在某个特定场合下他们将会需要另一种 编码值,如果不区分大小写的话,otherString 就会被包含进去…此时或许可以返回 -2呢?谁知道呢。
毕竟,我们有非常多关于NULL——价值亿万美金的错误的讨论。为什么不开始讨论 -1呢,某种意义上来说 -1 是 null 在int类型下的另一种形式。
4.避免意外的赋值
是的。即使最优秀的程序员也可能犯这种错误(当然,不包括我。看#7)。
(假设这是JavaScript,我们暂且偏执地认为是这种语言)
Java代码
// Ooops
if
(variable =
5
) { ... }
// Better (because causes an error)
if
(
5
= variable) { ... }
// Intent (remember. Paranoid JavaScript: ===)
if
(
5
=== variable) { ... }
再说一遍。如果你的表达式中有常量,将它放在等式左边。这样当你打算再添加一个 = 时,不容易出错。
5.检查null和长度
不管什么时候你有一个集合、数组或者其他的,确保它存在并且不为空。
Java代码
// Bad
if
(array.length >
0
) { ... }
// Good
if
(array !=
null
&& array.length >
0
) { ... }
你不知道这些数组来自哪儿,也许是早期的JDK API呢?
6.所有的方法都用 final 声明
你可以告诉我任何你想要的开闭原则,不过那都是胡说八道。我不相信你(可以正确继承我的类),也不相信我自己(不会意外地继承我的类)。因此除了接口(专门用于继承)都应该是严格的 final。可以查看我们的
Java编码中10个微妙的最佳实践
中的#9。
Java代码
// Bad
public
void
boom() { ... }
// Good. Don‘t touch.
public
final
void
dontTouch() { ... }
是的,写成final。如果这样做对你来说没有意义,你也可以通过修改或重写字节码来改变类和方法,或者发送功能请求。我敢肯定重写类/方法并不是一个好主意。
7.所有的变量和参数都用final声明
就像我说的。我不相信自己不会无意间重写了某个值。这么说来,我的确一点都不相信自己。因为:
这也是为什么所有的变量和参数都用final声明的原因。
Java代码
// 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 中 直到那该死的编译器停止工作,然后他们突然链接到了错误的方法,认为这一切都是你的错(事情总是这样)。
思考一下这个:
Java代码
// 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) {
...
}
因为,你知道的…你的用户们,他们就像这样
Java代码
// This library sucks
@SuppressWarnings
(
"all"
)
Object t = (Object) (List) Arrays.asList(
"abc"
);
bad(t);
相信我,我看过的多了,还有这样的
所以说偏执是有好处的。
9.总是在switch语句里加上default
Switch…作为最滑稽的表达式之一,我不知道是该心存敬畏还是默默哭泣。不管怎样,我们既然无法摆脱 switch ,在必要的时候我们最好能够正确使用它,例如:
Java代码
// 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是最坑爹的语句,任何喝醉了或是赌输了的人都可以在某种语言中使用它。看看下面这个例子:
Java代码
// 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了。因为你知道…..
https://youtu.be/oO3YmT2d-8k
现在,轮到你了!
你在编程时有哪些强迫症呢?
[Java]剑走偏锋的10条编程技巧
原文:http://blog.csdn.net/erlib/article/details/49246579
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年09月23日 (328)
2021年09月24日 (313)
2021年09月17日 (191)
2021年09月15日 (369)
2021年09月16日 (411)
2021年09月13日 (439)
2021年09月11日 (398)
2021年09月12日 (393)
2021年09月10日 (160)
2021年09月08日 (222)
最新文章
更多>
2021/09/28 scripts
2022-05-27
vue自定义全局指令v-emoji限制input输入表情和特殊字符
2022-05-27
9.26学习总结
2022-05-27
vim操作
2022-05-27
深入理解计算机基础 第三章
2022-05-27
C++ string 作为形参与引用传递(转)
2022-05-27
python 加解密
2022-05-27
JavaScript-对象数组里根据id获取name,对象可能有children属性
2022-05-27
SQL语句——保持现有内容在后面增加内容
2022-05-27
virsh命令文档
2022-05-27
教程昨日排行
更多>
1.
list.reverse()
2.
Django Admin 管理工具
3.
AppML 案例模型
4.
HTML 标签列表(功能排序)
5.
HTML 颜色名
6.
HTML 语言代码
7.
jQuery 事件
8.
jEasyUI 创建分割按钮
9.
jEasyUI 创建复杂布局
10.
jEasyUI 创建简单窗口
友情链接
汇智网
PHP教程
插件网
关于我们
-
联系我们
-
留言反馈
- 联系我们:wmxa8@hotmail.com
© 2014
bubuko.com
版权所有
打开技术之扣,分享程序人生!