在沉浸于编码一段时间以后,你会渐渐对这些东西习以为常。因为,你知道的……

  任何事情有可能出错,没错,的确如此。

  这就是为什么我们要采用“防御性编程”,即一些偏执习惯的原因。下面是我个人认为的10个最有用但偏执的Java编程技术。一起来看一看吧:

 1.将String字符串放在最前面

  为了防止偶发性的NullPointerException 异常,我们通常将String放置在equals()函数的左边来实现字符串比较,如下代码:

Java
// Badif (variable.equals("literal")) { ... }// Goodif ("literal".equals(variable)) { ... }

  这是随便用脑子想想就可以做的事,从Bad版本的代码改写表达式到Good版本的代码,这中间并不会丢失任何东西。欢迎不同的观点…

 2.不要相信早期的JDK API

  在Java早期,编程是一件非常痛苦的事情。那些API仍然很不成熟,也许你已经碰到过下面的代码块:

Java
String[] files = file.list();// Watch outif (files != null) {for (int i = 0; i < files.length; i++) {...}}

  看上去很偏执?也许吧,但请看Javadoc:

  如果这个虚拟路径不表示一个文件夹目录,则此方法返回null。否则将会返回一个字符串数组,每一个字符串表示目录中的文件或文件夹。

  对,没错。我们可以添加一些校验:

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

 3.不要相信“-1”

  我知道这是偏执的,但Javadoc中对 String.indexOf()方法明确指出:对象内第一次出现指定字符的位置索引,如果为-1则表示该字符不在字符序列中。

  所以使用-1是理所当然的,对吗?我说不对,请看以下代码:

Java
// Badif (string.indexOf(character) != -1) { ... }// Goodif (string.indexOf(character) >= 0) { ... }

  谁知道呢。也许到时候他们改变了编码方式,对字符串并不区分大小写,也许更好的方式是返回-2?谁知道呢。

 4.避免意外赋值

  是的。这种事情也许经常会发生。

Java
// Ooopsif (variable = 5) { ... }// Better (because causes an error)if (5 = variable) { ... }// Intent (remember. Paranoid JavaScript: ===)if (5 === variable) { ... }

  所以你可以将比较常量放置在左侧,这样就不会发生意外赋值的错误了。

 5.检查Null和Length

  无论如何,只要你有一个集合、数组等,请确保它存在,并且不为空。

Java
// Badif (array.length > 0) { ... }// Goodif (array != null && array.length > 0) { ... }

  你并不知道这些数组从哪里来,也许是来自早期版本的JDK API,谁知道呢。

 6.所有的方法都是final的

  你也许会告诉我你的开/闭原则,但这都是胡说八道。我不相信你(正确继承我这个父类的所有子类),我也不相信我自己(不小心继承我这个父类的所有子类)。所以对于那些意义明确的方法要严格用final标识。

Java
// Badpublic void boom() { ... }// Good. Don't touch.public final void dontTouch() { ... }

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

  就像我说的。我不相信我自己(不要意外覆盖我的值)。话虽如此,我不相信我自己的是因为…

  …这就是为什么所有的变量和参数都是final的原因。

Java
// Badvoid input(String importantMessage) {
String answer = "...";
answer = importantMessage = "LOL accident";}
// Goodfinal void input(final String importantMessage) {final String answer = "...";}

 8.重载时不要相信泛型

  是,它可以发生。你相信你写的超级好看的API,它很直观,随之而来的,一些用户谁只是将原始类型转换成Object类型,直到那该死的编译器停止发牢骚,并且突然他们会链接错误的方法,以为这是你的错误。

  看下面的代码:

Java
// Bad<T> void bad(T value) {bad(Collections.singletonList(value));}
<T> void bad(List<T> values) {...}
// Goodfinal <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
// Badswitch (value) {case 1: foo(); break;case 2: bar(); break;}
// Goodswitch (value) {case 1: foo(); break;case 2: bar(); break;default:throw new ThreadDeath("That'll teach them");}

  当value == 3时,将会出现无法找到的提示,而不会让人不知所谓。

 10.Switch语句带花括号

  事实上,switch是最邪恶的语句,像是一些喝醉了或者赌输了的人在写代码一样,看下面的例子:

Java
// Bad, doesn't compileswitch (value) {case 1: int j = 1; break;case 2: int j = 2; break;}// Goodswitch (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语句甚至不是真正的语句,他们就像goto语句中的跳转标记一样。

 结论

  偏执编程看起来似乎不可思议,有时,因为代码经常被证明是更详细一点,但并不是需求需要。你可能会想,“哦,这是绝不会发生的”,但正如我所说。经过20年左右的时间编程,你不希望只修复这些愚蠢的bug,因为编程语言是如此的陈旧的和有缺陷的。因为你知道…

  现在到你了!什么是你在编程最偏执的怪癖?

10个实用的但偏执的Java编程技术的更多相关文章

  1. (转载)10个实用的但偏执的Java编程技术

    10个实用的但偏执的Java编程技术 在沉浸于编码一段时间以后(比如说我已经投入近20年左右的时间在程序上了),你会渐渐对这些东西习以为常.因为,你知道的…… 作者:小峰来源:码农网|2015-09- ...

  2. 转载:10个实用的但偏执的Java编程技术

    在沉浸于编码一段时间以后(比如说我已经投入近20年左右的时间在程序上了),你会渐渐对这些东西习以为常.因为,你知道的…… 任何事情有可能出错,没错,的确如此. 这就是为什么我们要采用“防御性编程”,即 ...

  3. Java基础知识强化49:10个实用的但偏执的Java编程技术

    1. 将String字符串放在最前面 为了防止偶发性的NullPointerException 异常,我们通常将String放置在equals()函数的左边来实现字符串比较,如下代码: // Bad ...

  4. Java编程技术之浅析JVM内存

    JVM JVM->Java Virtual Machine:Java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. 基本认知: ...

  5. Java编程技术之浅析Java容器技术

    Java容器 集合是一种存储数据的容器,是Java开发中使用最频繁的对象类型之一. 或许提起Collection,都会第一时间意识到List和Set以及Map等相关关键词.因为这几乎是我们日常开发里接 ...

  6. Java编程技术之浅析SPI服务发现机制

    SPI服务发现机制 SPI是Java JDK内部提供的一种服务发现机制. SPI->Service Provider Interface,服务提供接口,是Java JDK内置的一种服务发现机制 ...

  7. Java编程思想 笔记

    date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...

  8. 深入剖析Java编程中的中文问题及建议最优解决方法

    摘录自:http://fafeng.blogbus.com/logs/3062998.html http://www.blogbus.com/fafeng-logs/3063006.html 深入剖析 ...

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

    本文由 ImportNew - LynnShaw 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得 ...

随机推荐

  1. List小结

    假设有两个List集合,找出集合中重复的部分: //检测listX和listY中的重复部分 //把X复制到Z避免循环同时操作X从而出现异常              itemX.ForEach(i = ...

  2. 4.接口隔离原则(Interface Segregation Principle)

    1.定义 客户端不应该依赖它不需要的接口: 一个类对另一个类的依赖应该建立在最小的接口上. 2.定义解读 定义包含三层含义: 一个类对另一个类的依赖应该建立在最小的接口上: 一个接口代表一个角色,不应 ...

  3. PL/pgSQL学习笔记之七

    http://www.postgresql.org/docs/9.1/static/plpgsql-declarations.html 如果一个PL/pgSQL函数声明了输出参数,输出参数被赋予$n名 ...

  4. PHPCMS教程

    第一章 模版 参见:http://blog.163.com/zh_astro/blog/static/1842084562011430430419/ 碎片管理: 在模版页面需要添加碎片的位置加上代码{ ...

  5. arp:地址解析协议(Address Resolution Protocol)(来自维基百科)

    地址解析协议(Address Resolution Protocol),其基本功能为通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。它是IPv4中网络层必不可少的协议,不过在I ...

  6. 记录一下centos安装httpd+php+mysql的过程

    1.安装apache httpd 这个貌似安装完centos后自带了,如果没有,也可以用yum安装 yum -y install httpd 2.安装php yum -y install php ph ...

  7. IOS 7 Study - Implementing Navigation with UINavigationController

    ProblemYou would like to allow your users to move from one view controller to the other witha smooth ...

  8. HDU 5573 Binary Tree 构造

    Binary Tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5573 Description The Old Frog King lives ...

  9. Linux内核探讨-- 第七章

    本文是个人分析<Linux内核设计与实现>而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/136 ...

  10. 比较长的sql语句

    SELECT o. * FROM hq_goods g LEFT JOIN hq_orders o ON o.goods_id = g.id WHERE o.user_id =73 AND o.sta ...