阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

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

  • 2013-12-17
  • 本文字数:2336 字

    阅读完需:约 8 分钟

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 中使用的接口范围过大。

2013-12-17 11:182218
用户头像

发布了 88 篇内容, 共 258.4 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

世界级计算机大神花两年总结出2000页深入理解计算机系统文档

爱好编程进阶

Java 面试 后端开发

FastDFS入门,Java编程笔试题及答案

爱好编程进阶

Java 面试 后端开发

Java-23种设计模式概述,手动实现一个简单的AOP框架

爱好编程进阶

Java 面试 后端开发

你知道Java是如何解决可见性和有序性问题的吗?,邮储银行Java笔试

爱好编程进阶

Java 面试 后端开发

从 Redux 源码谈谈函数式编程

有道技术团队

JavaScript Redux

SpringBoot+JWT+Shiro,linux高级编程面试题

爱好编程进阶

Java 面试 后端开发

【并发编程系列12】从Java线程池的常用4种写法深入分析线程池(Thread Pool)的实现原理

爱好编程进阶

Java 面试 后端开发

SpringMVC之Interceptor拦截器之登录拦截器,阿里巴巴java面试题

爱好编程进阶

Java 面试 后端开发

2022-04微软漏洞通告

火绒安全

安全 终端安全 漏洞检测 漏洞防护

海洋元宇宙Aquqnee,给人们全新游戏体验

BlockChain先知

无聊科技正经事(第1期):裁员毕业潮,你焦虑吗?

潘大壮

裁员 周刊 科技

Java 定时任务技术趋势

阿里巴巴云原生

【阿里Java岗的魔鬼三面】狠心刷完这6份pdf,java关于异常的面试题

爱好编程进阶

Java 面试 后端开发

Sentinel FlowSlot 限流实现原理(文末附流程图与总结),50家大厂面试万字精华总结

爱好编程进阶

Java 面试 后端开发

Flutter 2.0的路由把我搞蒙了!!!

岛上码农

flutter 路由 移动端开发 4月月更 跨平台开发

JavaEE框架学习笔记——SpringMVC篇,java集合详解和集合面试题目

爱好编程进阶

Java 面试 后端开发

mybatis-plus如何自动填充字段创建时间和修改时间,10天拿到阿里Java岗offer

爱好编程进阶

Java 面试 后端开发

源声|操作系统十年磨一剑,幕后的坚挺、不懈与客户第一

OpenTEKr

Linux 开源 操作系统 社区运营

建议收藏!总结了42种前端常用布局方案

云智慧AIOps社区

CSS html 前端 大前端 HTML5, CSS3

DevSecOps:云原生安全风险“避坑”指南

York

容器 云原生 安全 DevSecOps

【Java 基础语法】纯 Java,springmvc面试题常问2022

爱好编程进阶

Java 面试 后端开发

分享一个在线考试系统,练手项目用他很香,java架构面试题

爱好编程进阶

Java 面试 后端开发

简单的常量和变量的运算实例

CRMEB

深入浅出 Ext4 块和 Inode 分配器的优化(上)

焱融科技

云计算 高性能 文件存储 文件系统

Github上都在疯找的阿里内部“全栈技能修炼”终于来了,中级java工程师面试题

爱好编程进阶

Java 面试 后端开发

银杏谷创始人陈向明博士谈云原生的投资策略与思考 | 云原生加速器观点

阿里巴巴云原生

三面头条+四面阿里+五面腾讯拿offer分享面经总结,java最新多线程面试题及答案

爱好编程进阶

Java 面试 后端开发

两个通宵熬出来的互联网大厂最新面试题收集整理1000道(七-并发编程-下篇),欢迎点赞收藏!!!

爱好编程进阶

Java 面试 后端开发

Docker 实战教程之从入门到提高(三)

Jerry Wang

Docker 容器 虚拟化 容器镜像 4月月更

HTTP 中 ServletContext 对象,java软件工程师面试话术

爱好编程进阶

Java 面试 后端开发

一天下载量突破9000000!限时分享:阿里Java架构师成长笔记

爱好编程进阶

Java 面试 后端开发

Java开发中常见的危险信号(下)_Java_张龙_InfoQ精选文章