文章曾经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所须要把握的外围常识,欢送Star和指教。
欢送关注我的公众号,文章每周更新。
很多 Java 初学者在开始编程时会呈现一些问题,这些问题并不是指某个特定畛域的问题,也不是指对某个业务不相熟而导致的问题,而是对基础知识不够相熟导致的问题。而就是这些问题让咱们编写了一些不够强壮的代码。
这篇文章会列举几种编程初学者经常呈现的一些问题,我置信这些问题多多少少也曾困扰着当初或已经的你。如果感觉文章不错,无妨点赞分享,让更多人跳过这些开发中的坑。
随处可见的 Null 值
我见过很多的代码会把 Null 值作为返回值,当你预期是一个字符串时,意外失去了一个 Null 值;当你预期失去一个 List 时,意外又失去了一个 Null 值,如果你不进行解决,那么你还会意外失去 NullPointerException
.
就像上面这样。
// 状况1
String userTag = getUserTag();
if (userTag.equals("admin")) { // NullPointerException
// ...
}
// 状况2
List<String> carList = getCarList();
for (String car : carList) { // NullPointerException
// ...
}
为了避免这种状况,你能够在 List 返回时给出一个空的汇合而不是 Null,如果是字符串,你能够把要确定有值对象放在比拟的后面。
if ("admin".equals(userTag)) {
// ...
}
// 或者
if (Objects.equals(userTag,"admin")){
// ...
}
没有进行空值查看
可能你思考到了下面的 Null 值状况,然而在理论解决时没有思考空值状况,比方字符空串空串 “”,或者汇合为空。那么在后续解决时又有可能失去一个 NullPointerException
. 所以你应该进行空值判断。
String userTag = getUserTag();
if (userTag != null && userTag.trim() != "") {
// ...
}
List<String> carList = getCarList();
if (carList != null && !carList.isEmpty()) {
// ...
}
疏忽的异样解决
异样解决总是一件烦人的事,而疏忽异样仿佛总有一种吸引人的魔力。我见过像上面这样的代码。
try {
List<String> result= request();
// ...
}catch (Exception e){
}
你没有看错,catch 中没有任何内容,起初呈现了问题,看着日志文件一片太平无迹可寻。异样是成心抛出来的,你应该正确处理它们或者持续抛出。而且同时,你该输入一行日志用来记录这个异样,不便当前的问题追踪。
没有开释资源
在读取文件或者申请网络资源时,总是须要进行 close 操作,这很重要,否则可能会阻塞其余线程的应用。然而初学者可能会遗记这一步操作。其实在 Java 7 开始,就提供了 try-with-resources
主动敞开资源的个性,只须要把关上的资源放入 try
中。
try (FileReader fileReader = new FileReader("setting.xml")) {
// fileReader.read();
// ...
} catch (Exception e) {
e.printStackTrace();
}
像下面这样,不须要在 finally
里手动调用 fileReader
的 close
办法敞开资源,因为放在 try
里的资源调用会在应用结束时主动调用 close
. 而且不论是否有异样抛出,这很实用。
ConcuretModificationException
总有一天你会遇到 ConcuretModificationException
,而后开始百度搜寻它的解决形式,这个异样最常见的场景是你在遍历一个汇合时进行更新操作,比方像上面这样。
List<String> list = new ArrayList<>();
list.add("a1");
list.add("b1");
list.add("b2");
list.add("c1");
for (String s : list) {
if ("b1".equals(s)) {
list.remove(s);
}
}
这个异样很有用途,因为 ArrayList 不是线程平安的汇合,假如你这边一边遍历,另一个线程不断更新,非线程平安汇合会导致你的遍历后果不正确,所以这个异样的存在是正当的。同理 HashMap 也是如此,对于 HashMap 之前曾经有一篇文章具体介绍了,能够参考 最通俗易懂的 HashMap 源码剖析解读。
短少正文
精确的正文能够救人于水火,这点有时候一点也不夸大。尽管说优良的代码自身就是十分好的正文,然而这理论开发起来,很少产生。正文并不需要你事无巨细的一一记录,然而你该在外围逻辑增加应有的正文,比方简单逻辑的实现思路,以后逻辑业务需要。某个判断的增加起因,某个异样的产生状况等等。这能够让你在将来的某一天须要回看当初的代码时感激本人。更能够让你在某天的甩锅中轻松胜出。
不进行代码测试
我见过有些共事在性能开发结束后间接扔给对接共事应用,而本人却没有通过任何测试,或者只是测试了某个简略的状况。测试是开发过程中的重要环节,没有通过严格测试的代码很难说没有问题,我感觉在性能开发结束后至多须要单元测试,非凡用例测试,集成测试以及其余模式的测试。严格的测试不仅能够第一工夫发现问题,更能够缩小前面不必要的对接调试工夫。
反复造轮子
你晓得的,Java 社区十分沉闷,存在着大量的第三方类库,开源作者可能破费了数年工夫去保护和欠缺类库,这些类库十分优良。同时 JDK 也提供了大量的罕用的性能封装。这些都能够为咱们的开发速度插上翅膀。所以,当你须要一个性能时候,应该首先看下 JDK 和曾经引入的类库中是否曾经存在雷同性能,而不是本人反复造轮子,而且大部分状况下你造的轮子还不如他人好。
上面举些例子。
- 你须要日志记录,能够应用 logback.
- 你须要网络操作,能够应用 netty.
- 你须要解析 JSON,能够应用 gson.
- 你须要解析表格,能够应用 apache poi.
- 你须要通用操作,能够应用 apache commons.
另外一种状况是,你可能不晓得某个性能在 JDK 中曾经实现,这时候你应该多多查看 JDK Document. 我就在工作中见到过共事手写字符串 split,为了获取工夫戳把 Date 对象转换到 Calendar.
短少必要的沟通
这个局部是和开发没有关系的,然而这个环节往往会影响最终的开发后果。进行具体的开发之前,你应该具体的沟通并了解性能的需要,这样你能力针对具体的需要写出不偏离理论须要的代码。有时候你很有可能因为短少必要的沟通,谬误了了解了需要,最终在开发结束后发现自己写的性能齐全没有用途。
没有代码标准
代码规范性十分重要,如果一个我的项目里充斥着各种稀奇古怪的代码标准,会让维护者非常头疼。而且软件行业高速倒退,对开发者的综合素质要求也越来越高,优良的编程习惯也能够进步软件的最终品质。比方:别树一帜的命名格调挑战浏览习惯;形形色色的错误码人为地 减少排查问题的难度;工程构造混 乱导致后续我的项目保护艰巨;没有鉴权的破绽代码易被黑客攻击;品质低下的代码上线之后漏洞百出等等。因为没有对立的代码标准,开发中的问题可能层出不穷。
上面简略列举些应该对立的开发标准。如命名格调如何是好;常量名称构造怎么;代码格局怎么对立;日期工夫格局如何解决;汇合解决注意事项;日志打印有无标准;前后交互具体规约等。
下面所说的开发标准代码标准举荐阿里推出的 《Java 开发手册》,外面具体列举了在 Java 开发中各个方面应该恪守的规约和标准。最新版本在 8月 3日曾经公布,能够在公众号 “未读代码” 间接回复 “java ” 获取最新版 pdf.
总结
Bug 和技术上的误会都是漂亮的谜团,福尔摩斯般的咱们终将解决这些问题。命运本人把握,每一次探清的这些技术误会,都会减少咱们对开发编码的了解。纵情接招吧,色彩斑斓才乏味,万般体验才是人生,不论是多样的技术,还是多样的问题,我都想看见。
参考:
[1] A beginner’s guide to Java programming nightmares
[2] Java™ Platform, Standard Edition 8 API Specification
最初的话
文章曾经收录在 Github.com/niumoo/JavaNotes ,欢送Star和指教。更有一线大厂面试点,Java程序员须要把握的外围常识等文章,也整顿了很多我的文字,欢送 Star 和欠缺,心愿咱们一起变得优良。
文章有帮忙能够点个「赞」或「分享」,都是反对,我都喜爱!
文章每周继续更新,要实时关注我更新的文章以及分享的干货,能够关注「 未读代码 」公众号或者我的博客。
发表回复