Java开发中常见的危险信号(下)

标签: java 开发 常见 | 发表时间:2013-12-18 09:24 | 作者:ricohzhanglong
出处:http://blog.csdn.net

本文来源于我在InfoQ中文站原创的文章,原文地址是: http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-3


Dustin Marx是一位专业软件开发者,从业已经有17年的时间,他拥有电子工程学士学位,还是一位MBA。Dustin维护着一个 博客,专门介绍软件开发的各个主题。近日,他 撰文谈到了Java开发中常见的 危险信号,提出了在日常的Java开发中我们需要尽力避免的一些不正确的做法。感兴趣的读者可以参见本系列文章的 第一部分第二部分

编译器警告与IDE或工具的警告、提示及发现

来自于 javac编译器的警告以及IDE和其他代码分析工具的提示信息是Java中明显的危险信号。可以这么说,几乎每一个警告与提示信息都是潜在的危险信号。事实上,我在文中所提及的很多危险信号都是来自于javac编译器或是其他工具与IDE的警告或提示信息。这些警告与提示信息不仅直接对应于很多Java代码的危险信号,而且他们一起出现时更是表明代码出现了严重的问题,这需要引起开发者的足够重视。

关闭编译器警告与IDE和工具的警告及提示信息

当然了,我并不认为FindBugs所标识出的Java代码中的每个问题都是Bug或是Defect。事实上,在某些情况下,我甚至会禁用掉某些提示信息,因为我并不认为这些提示信息是正确的,他们会搞乱FindBugs的输出。也就是说,如果关闭提示信息你需要非常谨慎才行,确保只忽略掉那些不正确的提示信息而保留下重要的警告信息。类似地,我倾向于开启很多IDE警告,不过会将其中一小部分关闭掉。我觉得在禁用掉javac警告的情况下来构建Java应用并不是明智之举。这样做会隐藏掉出现的危险信号,不过关闭这些警告信息的动作本身很可能就是个更大的危险信号,因为这些警告与提示信息会指出很多潜在的危险信号,需要你重点关注。

过度工程化与过早优化

过于复杂的软件通常是一种常见的 开发者失调行为的结果。为了代码的灵巧而丧失可读性,或是 关注于灵活性及进行没必要的 过早优化而造成可读性的降低常常会导致其他问题的产生。过度工程化的开发者常常会这么做,看看能否用点什么新玩儿意,不过这对于高质量的软件来说却并没有什么好处。一旦软件变得过于复杂并且难以理解,那么维护起来就不是那么容易的事情了,而且常常会导致修改时出现问题。

举个例子,在阅读代码时你可能想知道为什么开发者没有采取更加直接的方式来实现。一方面,你可能感叹于开发者能够使用一些更加高级的特性,但另一方面,你可能又会觉得这么做要比正常情况更加复杂了。有很多事实可以证明这是一个危险信号,不过我只在几个地方看到有人会这么做。一种情况是将本来用静态Java代码实现好好的众多功能改用反射、Spring或是其他依赖注入、动态代理、观察者模式等方式来实现。如果用得好的话当然没什么问题,不过我经常看到有人过度使用或是滥用这些特性,这直接导致其他开发者很难理解代码的意图与作用。

将日志消息直接输出到控制台

Java中的日志框架由来已久,如今已经有为数不少的 日志框架(有些框架构建在别的框架之上),这包括传统的Log4j 1.2、Log4j 2、java.util.logging(Java Logging API)、Apache Commons Logging及SLF4J等。既然有这么多的日志框架,因此我会很奇怪为什么很多Java代码中还有System.out与System.err语句。

Java代码中存在着向 标准输出与标准错误中进行输出可能有很多原因。其中一个原因就是有些代码还不太成熟,后面还会修改,改成输出到日志,不过到最后也没有改。使用标准输出与标准错误的另一个弊端就是这些日志消息并不会被写到日志文件中,而使用日志框架的日志消息则会被写到文件中,这样就会出现不一致的情况。第3个问题就是日志框架提供了不少优秀的特性,如果直接写到标准输出或是标准错误中就无法使用这些特性了。这些特性包括轻松控制日志消息的级别、轻松将捕获到的异常关联到一个日志错误消息上、轻松将输出重定向到不同的目标及使用不同的格式等。虽然在直接使用输出与错误流时这些都可以通过手工来实现,不过这需要自己编写代码而不是“开箱即用的”。

除了直接使用System.out与System.err外,有些Java代码还是会将信息写到标准输出与标准错误上(通常也是隐含使用了System.out与System.err)。比如说, Throwable.printStackTrace()(在处理异常时常常会用到)就会这么做,根据Javadoc的说明,它会将异常与堆栈信息打印到标准错误流中。

使用StringBuffer而非StringBuilder

坦白地说,这只是个小问题而已,不过却能标识出 过时的Java代码(StringBuffer是JDK 1.0引入的,而StringBuilder则是J2SE 5引入的)或是开发者并没有真正理解他们之间的区别。在大多数情况下,这两者之间的性能差别对于应用来说是微乎其微的,但由于StringBuilder更适合于大多数使用了StringBuffer的场景,因此我们还是可以从StringBuilder获得性能上的微小提升。 我很少发现使用StringBuffer而不能使用StringBuilder的情况。

方法与构造方法中使用了过多的参数

当方法与构造方法拥有太多的参数时,我总是担心客户端无法正确地使用他们,特别是有些参数是相同类型的情况。如果一个方法接收了3个字符串和3个布尔值,那么客户端就很容易搞混传递进去的值。编译器在这种情况下也无能为力,检测问题的唯一办法就是在运行期(通过单元测试或是其他测试)查看调用结果。过多的参数表明了不恰当的设计。

过多的显式类型转换

显式类型转换最有可能是个危险信号,因为类型转换本身并不会影响到任何功能或是逻辑,不过这却表明情况与预想的不一致。类型转换表明了不太好的设计决策(比如说没有正确利用好多态、在不合适的地方使用了继承、或是强制将一些本不该放在一些的东西放到了一起)。当然了,显式类型转换在很多情况下是恰当和必要的(比如说在获取Spring框架的Bean时),不过有时也表明设计上出现了问题。类型转换还表明API定义的范围过大或是API中使用的接口范围过大。

作者:ricohzhanglong 发表于2013-12-18 1:24:02 原文链接
阅读:74 评论:0 查看评论

相关 [java 开发 常见] 推荐:

Java开发中常见的危险信号(下)

- - CSDN博客推荐文章
本文来源于我在InfoQ中文站原创的文章,原文地址是:. Dustin Marx是一位专业软件开发者,从业已经有17年的时间,他拥有电子工程学士学位,还是一位MBA. Dustin维护着一个 博客,专门介绍软件开发的各个主题. 近日,他 撰文谈到了Java开发中常见的 危险信号,提出了在日常的Java开发中我们需要尽力避免的一些不正确的做法.

Java开发中常见的危险信号

- - Java - 编程语言 - ITeye博客
这里将要谈及的很多“危险信号”通常都会收到来自于FindBugs等代码分析工具所发出的警告信息,流行的Java IDE也会将它们标记出来. 不过,我发现有不少开发者会忽略掉这些来自于工具与IDE的警告信息,要么是因为他们关掉了提示信息,要么是出于自身的开发习惯或是不理解与这些警告信息所关联的风险,因此会忽略掉警告信息.

Java常见疑惑和陷阱(PPT)

- water - BlogJava-首页技术区
本来是打算小范围内讨论的,话题也比较小,后来听说人多了,临时拼凑些材料. 话题过大后重点就放在讲解上,其实这里面讲解的东东还是挺多的. 以后有时间会将并发完整整理一次. xylz 2010-12-03 16:13 发表评论.

Java String 的十大常见问题

- - ITeye博客
Java字符串经常被问到的排名前十的问题.    1、如何比较字符串. 使用 “==”  还是 “equals()”.   简单来讲,“==”比较的是引用(对象的内存地址),“equals()” 比较值是否相等. 除非你想检测两个字符串是否是同一对象,否则都用equals().   当然了解字符串池的概念更好.

Java Socket常见异常处理

- - BlogJava-qileilove
java网络编程Socket通信中,通常会遇到以下异常情况:.   第1个异常是 java.net.BindException:Address already in use: JVM_Bind.   该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时.

java代码开发规范

- - BlogJava_首页
格式规范:                                                                      .       1、TAB空格的数量. 编辑器上的TAB空格数量统一取值为4.       2、换行, 每行120字符.       3、if语句的嵌套层数3层以内   .

Apache Thrift - java开发详解

- - 编程语言 - ITeye博客
2、编写IDL文件 Hello.thrift. 4、编写实现类、实现Hello.Iface:. 5、编写服务端,发布(阻塞式IO + 多线程处理)服务.      * 阻塞式、多线程处理 .             //设置传输通道,普通通道  .             //使用高密度二进制协议  .

[译] JAVA初学者的30个常见问题

- - 博客园_首页
本文回答了30个JAVA入门级初学者的常见问题. a += b 和 a = a + b 的效果有区别吗. 声明一个数组为什么需要花费大量时间. 为什么JAVA库不用随机pivot方式的快速排序. Q. 为什么 -0/3 结果是 0,而  -0.0/3.0 结果是 -0.0. A. 在Java里,整数是用补码表示的.

10种常见的Java不规范代码

- - 编程语言 - ITeye博客
1、在Eclipse中格式化源代码并管理import语句:. Eclipse提供了自动格式化源代码和管理import语句的功能(并移除未使用的语句). 你可以使用下面的快捷键来使用这些功能. Ctrl + Shift + F – 格式化源代码. Ctrl + Shift + O – 管理import语句并移除未使用的语句.

十个最常见的Java字符串问题 - liushaobo

- - 博客园_首页
翻译自: Top 10 questions of Java Strings. 用”==”还是用equals(). 简单地说,”==”测试两个字符串的引用是否相同,equals()测试两个字符串的值是否相同. 除非你希望检查两个字符串是否是同一个对象,否则最好用equals(). 2.为什么对于安全性敏感的信息char[]要优于String.