阅读更多

6顶
1踩

编程语言

转载新闻 偏执却管用的10条Java编程技巧

2015-10-15 13:46 by 副主编 mengyidan1988 评论(5) 有7614人浏览
经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯。因为,你知道…

任何可能出错的事情,最后都会出错。

这就是人们为什么喜欢进行“防错性程序设计”的原因。偏执的习惯有时很有意义,有时则不够清晰也不够聪明,也许当你想到这样写的人的时候还会觉得有点怪异。下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看:

1.把字符串常量放在前面

通过把字符串常量放在比较函数equals()比较项的左侧来防止偶然的 NullPointerException 从来都不是一个坏主意,就像这样:
// Bad
if (variable.equals("literal")) { ... }
 
// Good
if ("literal".equals(variable)) { ... }

这是毫无疑问的,把一种表达式转换成另一种更好的表达式,并不会失去什么。只要我们的Options是真实存在的(Java 8中 Optional是对可以为空的对象进行的封装),不是吗?讨论一下…

2.不要相信早期的JDK APIs

Java刚出现的时候,编程一定是件很痛苦的事。那时的API仍然不够成熟,你可能曾经遇到过这样一段代码:
String[] files = file.list();
 
// Watch out
if (files != null) {
    for (int i = 0; i < files.length; i++) {
        ...
    }
}

看起来很奇怪对吗?也许吧,但是看看这个Javadoc

“如果抽象路径名表示的不是一个目录,那么这个方法返回null。否则返回一个字符串数组,其中每个字符串表示当前目录下的一个文件或目录。”

是的,最好再加上判空检查,以确保正确:
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 就可以理所当然被拿来用,对吗?我说不对,看看这个:
// Bad
if (string.indexOf(character) != -1) { ... }
 
// Good
if (string.indexOf(character) >= 0) { ... }

谁知道呢。也许在某个特定场合下他们将会需要另一种 编码值,如果不区分大小写的话,otherString 就会被包含进去…此时或许可以返回 -2呢?谁知道呢。

毕竟,我们有非常多关于NULL——价值亿万美金的错误的讨论。为什么不开始讨论 -1呢,某种意义上来说 -1 是 null 在int类型下的另一种形式。

4.避免意外的赋值

是的。即使最优秀的程序员也可能犯这种错误(当然,不包括我。看#7)。

(假设这是JavaScript,我们暂且偏执地认为是这种语言)
// Ooops
if (variable = 5) { ... }
 
// Better (because causes an error)
if (5 = variable) { ... }
 
// Intent (remember. Paranoid JavaScript: ===)
if (5 === variable) { ... }

再说一遍。如果你的表达式中有常量,将它放在等式左边。这样当你打算再添加一个 = 时,不容易出错。

5.检查null和长度

不管什么时候你有一个集合、数组或者其他的,确保它存在并且不为空。
// Bad
if (array.length > 0) { ... }
 
// Good
if (array != null && array.length > 0) { ... }

你不知道这些数组来自哪儿,也许是早期的JDK API呢?

6.所有的方法都用 final 声明

你可以告诉我任何你想要的开闭原则,不过那都是胡说八道。我不相信你(可以正确继承我的类),也不相信我自己(不会意外地继承我的类)。因此除了接口(专门用于继承)都应该是严格的 final。可以查看我们的Java编码中10个微妙的最佳实践中的#9。
// Bad
public void boom() { ... }
 
// Good. Don't touch.
public final void dontTouch() { ... }

是的,写成final。如果这样做对你来说没有意义,你也可以通过修改或重写字节码来改变类和方法,或者发送功能请求。我敢肯定重写类/方法并不是一个好主意。

7.所有的变量和参数都用final声明

就像我说的。我不相信自己不会无意间重写了某个值。这么说来,我的确一点都不相信自己。因为:



这也是为什么所有的变量和参数都用final声明的原因。
// 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 中 直到那该死的编译器停止工作,然后他们突然链接到了错误的方法,认为这一切都是你的错(事情总是这样)。

思考一下这个:
// 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) {
    ...
}

因为,你知道的…你的用户们,他们就像这样
// This library sucks
@SuppressWarnings("all")
Object t = (Object) (List) Arrays.asList("abc");
bad(t);

相信我,我看过的多了,还有这样的



所以说偏执是有好处的。

9.总是在switch语句里加上default

Switch…作为最滑稽的表达式之一,我不知道是该心存敬畏还是默默哭泣。不管怎样,我们既然无法摆脱 switch ,在必要的时候我们最好能够正确使用它,例如:
// 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是最坑爹的语句,任何喝醉了或是赌输了的人都可以在某种语言中使用它。看看下面这个例子:
// 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

现在,轮到你了!

你在编程时有哪些强迫症呢?

原文链接:javacodegeeks 翻译:ImportNew.com - LynnShaw
译文链接:http://www.importnew.com/16805.html
  • 大小: 35.3 KB
  • 大小: 23.3 KB
来自: ImportNew.com
6
1
评论 共 5 条 请登录后发表评论
5 楼 mangguo 2015-10-19 09:38
写过一些java的基础类的学习资料,请指导:
http://www.hubwiz.com/course/555999807f0619e7325a6e78/
4 楼 ronnin 2015-10-19 09:09
挖坟?
http://www.iteye.com/news/30908
3 楼 sonckchi 2015-10-18 14:17
总结的不错!
2 楼 yixiandave 2015-10-15 18:49
用sql替换空格的那个也是大神啊
1 楼 506722178 2015-10-15 17:51
很有学习意义,从来没有这样写过,都是怎么写的少怎么写

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 系统分析师学习笔记(十一)

    系统分析 系统分析阶段也称为逻辑设计阶段,其任务是根据系统设计任务书所确定的范围,对现有系统进行详细调查,描述现有系统的业务流程,指出现有系统的局限性和不足之处,确定新系统的基本目标和逻辑功能要求,即提出新系统的逻辑模型。系统分析阶段的工作成果体现在系统需求规格说明书中,这是系统建设的必备文件,是系统设计阶段的工作依据,也是将来系统验收的依据。 系统分析概述 1.系统分析的任务 系统分析阶段的基本任务是系统分析师和用户在充分了解用户需求的基础上,把双方对新系统的理解表达为系统需求规格说明书。 2.系统分析的

  • 驰骋 bpm_实际BPM的协作方法

    驰骋 bpm 我们已经在业务流程管理(BPM)领域中工作了多年,很有趣的是,最近对它的关注日益增加。 引起这种兴趣的催化剂可能是工具的日趋成熟,BPMN标准的新2.0版本,由更多出版物引起的更好的理解或BPM方法的改进的先决条件,仅列举了BPM中最重要的几个发展。 供应商提供了越来越多的高级图形工具,这些工具可以使业务流程实现自动化,而无需任何编码甚至开发人员。 但是,我们发现这些以“供应商...

  • 《信息工程》读书笔记

    可行性研究包括 明确任务、调查环境、提出方案和可行性分析 四个方面 企业系统规划法是一种对企业 管理信息系统 进行规划和设计的结构化方法,它是由美国的 IBM 公司在20世纪60年代末创造并逐步发展起来的。 防火墙在逻辑上是一个 隔离器、 过滤器 、监视器 按照是否需要执行被测系统的角度来分,可将测试分为 静态 测试和 动态 测试 项目开发策略通常有 线性法、 线性迭代法 、原型法 和复合法 数据流图的基本元素包括 处理、 数据流 、实体 以及数据存储等 数据字典通常由数据流、 文件

  • 读书笔记:信息化战略几个关键组成

    信息化战略最终要形成整体信息规划以及战略部署,最终战略形成的内容包括三个最重要组成部分:信息系统架构战略、信息基础设施战略、信息资源整合战略以及主要信息系统的选择。 一、信息系统架构战略 信息系统架构是指应用程序、技术和数据的相应选择和投资组合的定义,以及对硬件、软件和通信的配置等。 信息系统架构战略就是对信息系统架构的整体安排。 二、信息化基础设施战略 实质上信息化基础设施是保障业务连...

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

    经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯。...下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看: 把字符串...

  • java 偏执却管用的10条Java编程技巧

    经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯。...下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看:1. 把字符串常量

  • java变_偏执却管用的10条Java变成技巧

    经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯。...下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看:1. 把字符串常...

  • 人力资源经理绩效考核表.xls

    人力资源经理绩效考核表

  • 智慧环卫管理平台建设方案Word(211页).docx

    一、智慧环卫管理平台的建设背景与目标 智慧环卫管理平台的建设源于对环卫管理全面升级的需求。当前,城管局已拥有139辆配备车载GPS系统、摄像头和油耗传感器的环卫车辆,但环卫人员尚未配备智能移动终端,公厕也缺乏信息化系统和智能终端设备。为了提升环卫作业效率、实现精细化管理并节省开支,智慧环卫管理平台应运而生。该平台旨在通过信息化技术和软硬件设备,如车载智能终端和环卫手机App,实时了解环卫人员、车辆的工作状态、信息和历史记录,使环卫作业管理透明化、精细化。同时,平台还期望通过数据模型搭建和数据研读,实现更合理的环卫动态资源配置,为环卫工作的科学、健康、持续发展提供决策支持。 二、智慧环卫管理平台的建设内容与功能 智慧环卫管理平台的建设内容包括运行机制体制建设、业务流程设计、智慧公厕系统建设、网络建设、主机和储存平台需求、平台运维管理体系、硬件标准规范体系以及考核评价体系等多个方面。其中,智慧公厕系统建设尤为关键,它能实时监控公厕运行状态,保障公厕的清洁和正常运行。平台建设还充分利用了现有的电子政务网络资源,并考虑了有线和无线网络的需求。在功能上,平台通过普查、整合等手段全面收集环卫车辆、企业、人员、设施、设备等数据,建立智慧环卫基础数据库。利用智能传感、卫星定位等技术实现环卫作业的在线监管和远程监控,实现对道路、公共场所等的作业状况和卫生状况的全面监管。此外,平台还建立了环卫作业网格化管理责任机制,实现从作业过程到结果的全面监管,科学评价区域、部门、单位和人员的作业效果。 三、智慧环卫管理平台的效益与风险规避 智慧环卫管理平台的建设将带来显著的环境、经济和管理效益。环境方面,它将有力推进环境卫生监管服务工作,改善环境卫生状况,为人民群众创造更加清洁、卫生的工作和生活环境。经济方面,通过智慧化监管,大大降低了传统管理手段的成本,提高了监管的准确性和效率。管理方面,平台能够追踪溯源市民反映的问题,如公厕异味、渣土车辆抛洒等,并找到相应的责任单位进行处置,防止类似事件再次发生。同时,平台还拥有强大的预警机制功能,能够在很多环卫问题尚未出现前进行处置。然而,平台建设也面临一定的风险,如部门协调、配合问题,建设单位选择风险以及不可预测的自然灾害等。为了规避这些风险,需要加强领导、统一思想,选择优秀的系统集成商承接项目建设,并做好计算机和应用系统的培训工作。同时,也要注意标准制定工作和相关法律法规的制定工作,以保证系统建设完成后能够真正为环卫管理工作带来便利。

  • apache-parent-10-14.el7.x64-86.rpm.tar.gz

    1、文件内容:apache-parent-10-14.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/apache-parent-10-14.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装

  • 用于卫星通信的CTS天线

    用于卫星通信的圆极化CTS天线研究

  • 人事档案登记及查询系统.xlsx

    人事档案登记及查询系统

  • 12 -防损部经理绩效考核表1.xlsx

    12 -防损部经理绩效考核表1

  • 泰尔指数模型stata全流程代码+数据+文献(数据权威)

    ## 一、泰尔指数模型stata全流程代码+数据+文献 参考C刊《农业经济问题》朱红根(2023)老师的做法,用泰尔指数是衡量个人或地区之间收入差距的重要指标,本文利用泰尔指数分析中国区域内和区域间数字乡村发展水平的差异,测算了全国总体差异、区域内差异、区域间差异以及相关贡献率。此资料包括stata全流程代码、案例数据、参考文献,用excel计算有标注有过程 ,并且参照文献讲的。 ## 二、2005-2021年城乡收入差距与泰尔指数:原始数据+测算结果 泰尔熵标准(Theil’s entropy measure)或者泰尔指数(Theil index)是衡量个人之间或者地区间收入差距(或者称不平等度)的指标。又称泰尔系数或锡尔指数,但我还是习惯叫泰尔指数。Theil指数用来表示区域经济差异状况,数值越大则差异程度越大。 数据名称:城乡收入差距与泰尔指数(原始数据+测算) 数据年份:2005-2021年 指标变量:泰尔指数、城镇收入占农村收入之比、城镇居民人均可支配收入、农村居民人均可支配收入、乡村人口、全体居民人均可支配收入、城镇人口、年末常住人口 测算公式:

  • 34 -配送部经理绩效考核表1.xlsx

    34 -配送部经理绩效考核表1

  • [2024最新更新]全国城投公司数据大全(数据权威)

    1.资料名称:2021-1998年城投公司数据大全 2.数据指标:序号、公司名称、区域、城投评分、省内排名、最新主体评级、行政等级、 股东背景、股权关系、平台重要性、城投口径、实控人、 总资产(亿元)、 货币资金(亿元)、土地资产(亿元)、受限资产(亿元)、应收账款(亿元) 应收类款项政府占比(%)、营业收入(亿元)、公益性&准公益性主营占比(%)、归母净利润(亿元)、政府补助(亿元)、总资产报酬率(%)、有息债务(亿元)、 短期债务(亿元)、借款(亿元)、债券余额(亿元)、私募债占比(%)、 非标融资(亿元)、资产负债率(%)、债务资本化比率(%) 对外担保比例(%)、EBITDA/利息(倍)、EBITDA全部债务比(%)、授信余额(亿元)、 最新报告期 、申万行业 城投公司是城市建设投资公司的简称,是全国各大城市政府投资融资平台,起源于1991年,承担相应的政府职能,是特殊市场经营体。 此类城投公司大多是不具备盈利能力的,属于事业单位或者国有独资公司性质,他们是通过政府补贴的方式实现盈利,属于带有政府性质的特殊市场经营体。

  • 推广立方连通圈网络的Hamilton分解的算法.pdf

    推广立方连通圈网络的Hamilton分解的算法.pdf

  • 材料员绩效考核表.xls

    材料员绩效考核表

  • 2023年全国大学生英语竞赛样题(A类).pdf

    2023年全国大学生英语竞赛样题(A类)

Global site tag (gtag.js) - Google Analytics