偶然看到阿里巴巴竟然出书了???趁着满减活动(节约节约....)我赶忙买来准备看看,刚拿到的时候掂量了好多下,总以为商家给我少发了一本书,结果打开才知道..原来这本书这么小....html
别人都说咱们是搬砖的码农,但咱们知道本身是追求个性的艺术家。也许咱们不会过多在乎本身的外表和穿着,但在咱们不羁的外表下,骨子里追求着代码的美、系统的美、设计的美,代码规范其实就是一个对程序美的定义。—— 引自 序java
若是有一天在咱们的项目中看到了这样的代码:mysql
或者是这样的代码:git
这样美不美呢?或许看着是还挺美的,可是若是须要修改,是否是人傻啦?github
那这样的代码呢?web
做为一个对本身有必定要求的程序猿,是否是第一反应就是:ajax
规范不一,就会像下图中的小鸭和小鸡对话同样,语言不通,一脸囧相。鸡同鸭讲也偏偏形容了人与人之间沟通的痛点,自说自话,没法达成一致意见。再举一个生活中的例子,交通规则靠左行驶仍是靠右行驶,二者孰好孰坏并不重要,重要的是必需要在统一的方向上通行,表面上限制了自由,但其实是保障了公众的人身安全。试想,若是没有规定靠右行驶,那样的路况确定拥堵不堪,险象环生。一样,过度自由随意、天马行空的代码会严重的伤害系统的健康,影响到可扩展性以及可维护性。sql
众所周知,互联网公司的优点在于效率,它是企业核心竞争力。体如今产品开发领域,就是够沟通效率和研发效率。对于沟通效率的重要性,能够从程序猿三大 “编码理念之争” 提及:数据库
在美剧《硅谷》中,有这样的一个经典镜头:编程
Tab 键和空格键的争议确实存在,而且在知乎上讨论得火热:写代码时,缩进使用 tab 仍是空格?
if 单语句是否须要换行,也是争论不休的话题。相对来讲,写过格式缩进类编程语言的开发者, 更加习惯于不加大括号。《手册》中明确 if/for 单行语句必须加大括号,由于单行语句的写法,容易在添加逻辑时引发视觉上的错误判断。此外,if 不加大括号还会有局部变量做用域的问题。
左大括号是否单独另起一行?由于 Go 语言的强制不换行,在这点上,“编程理念之争” 的硝烟味彷佛没有那么浓。若是必定要给一个理由,那么换行的代码能够增长一行,对于按代码行数考核工做量的公司员工,确定倾向于左大括号前换行。《手册》明确左大括号不换行!
这一章是对传统意义上的代码规范,包括变量命名、代码风格、控制语句、代码注释等基本的变成习惯,以及从高并发场景中提炼出来的集合处理技巧与并发多线程的注意事项。
- 反例:
_name
/$name
/name_
/name$
尽管 $
能够做为标识符使用,然而咱们应该尽可能避免对其使用。
$
一般在编译器生成的标识符名称中使用,若是咱们也使用这个符号,可能会有一些意想不到的错误发生....package test; public class User$VIP { public static void main(String[] args) { User user = new User(); User.VIP vip = user.new VIP(); vip.print(); } } class User{ class VIP{ void print(){ System.out.println("成员类"); } } }
仔细阅读如下,彷佛并无什么问题,代码也比较简单,但正在咱们编译的时候,IDEA提示咱们:
定义了重复的代码?归根到底,都是 $
惹的祸!由于 $
被编译器所使用,在源文件(.java 文件)编译成字节码(.class 文件)后,会称为顶层类型与嵌套类型之间的链接符。例如,若是存在一个顶层类 A,在其内声明了一个成员类 B,那么编译以后就会产生两个 class 文件,分别为 A.class
与 A$B.class
。
就本程序来讲,会生成 3 个 class 文件(若是能够编译的话),分别是 User$VIP.class
(顶层类)、User.class
与 User$VIP.class
(User 类的成员类,也就是类 VIP)。因为试图存在两个 User$VIP.class
因此才会报错!
变量命名所有大写,单词兼用下划线隔开,力求予以表达完整清楚,不要嫌名字太长。
正例:MAX_STOCK_COUNT / PRIZE_NUMBER_EVERYDAY
反例:MAX_COUNT / PRIZE_NUMBER
抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类名开始,以 Test 结尾。
反例:定义为基本数据类型
Boolen isDeleted;
的属性,它的方法名称也是isDeleted()
,RPC 框架在反向解析的时候,“误觉得” 对应的属性名称是deleted
,致使属性获取不到抛出异常。
说明: 将设计模式体如今名字中,有利于阅读者快速理解架构设计理念。
正例:
public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
正例:
接口方法签名:void commit();
接口基础变量:String COMPANY = "alibaba";
反例:
接口定义方法:public abstract void commit();
正例: CacheServiceImpl 实现 CacheServcie 接口
2):【推荐】 若是是形容能力的接口名称,取对应的形容词为接口名(一般是 -able 的形式)。
正例: AbstractTranslator 实现 Translatable。
Long a = 2l;
写得是数字的 21 仍是 Long 型的 2?说明: 大而全的变量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。
正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在 ConfigConsts 下。
public static void main(String[] args){ // 注释的双斜线与注释内容之间有且仅有一个空格 // 缩进 4 个空格 String say = "hello"; // 运算符的左右必须有 1 个空格 int flag = 0; // 关键字 if 与括号之间必须有 1 个空格,括号内的 f与左括号、 // 0 与右括号之间不须要空格 if (flag == 0) { System.out.println(say); } // 左大括号前加空格且不换行;左大括号后换行 if (flag == 1) { System.out.println("world"); // 右大括号前换行,右大括号后有 else,不用换行 } else { System.out.println("ok"); // 在右大括号后直接结束,则必须换行 } }
正例:下例中实参的“one”,后边必需要有一个空格。
method("one", "two", "three");
Intergre var = ?
在 -128~127 范围内的赋值, Integer 对象是在 IntegerCache.cache 中产生的,会复用已有的对象,这个区间内的 Integer 值能够直接使用 == 进行判断,可是这个区间以外的全部数据,都会在堆上产生,并不会复用已有对象。这是一个大坑,推荐使用 equals 方法进行判断。// 正例 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (删除元素的条件) { iterator.remove(); } } // 反例 List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); for (String item : list) { // 若是把 1 改成 2 再试一下看看是否相同 if ("1".equals(item)) { list.remove(item); } }
if (condition) statements;
反例:判断剩余奖品数量等于 0 时,终止发放奖品,但由于并发处理错误致使奖品数量瞬间变成了负数,这样的话,活动没法终止。
// 正例:超过 3 层的 if-else 逻辑判断代码可使用卫语句、策略模式 // 状态模式等来实现,其中卫语句实例以下: public void today() { if (isBusy()) { System.out.println("change time,"); return; } if (isFree()) { System.out.println("go to travel."); return; } System.out.println("stay at home to learn Java"); return; }
/**内容*/
格式,不得使用 //xxx
方式“安全生产,责任重于泰山。” 这句话一样适用于软件生产,本章主要说明编程中须要注意的比较基础的安全准则。
说明: MySQL 在 Windows 下不区分大小写,但在 Linux 下默认区分大小写。所以,数据库名、代表、字段名都不容许出现任何大写字母,避免节外生枝。
正例: getter _ admin , task _ config , level 3_ name
反例: GetterAdmin , taskConfig , level 3 name
正例: tiger _ task / tiger _ reader / mpp _ config
正例:以下表,其中无符号值能够避免误存负数,且扩大了表示范围。
对象 | 年龄区间 | 类型 | 表示范围 |
---|---|---|---|
人 | 150 岁以内 | unsigned tinyint | 无符号值:0 到 255 |
龟 | 数百岁 | unsigned smallint | 无符号值:0 到 65535 |
恐龙化石 | 数千万年 | unsigned int | 无符号值:0 到约 42.9 亿 |
太阳 | 约 50 亿年 | unsigned bigint | 无符号值:0 到约 10 的 19 次方 |
正例: where a =? and b =? order by c; 索引: a _ b _ c
反例:索引中有范围查找,那么索引有序性没法利用,如: WHERE a >10 ORDER BY b; 索引 a _ b 没法排序。
正例:若是 where a =? and b =? , a 列的几乎接近于惟一值,那么只须要单建 idx _ a 索引便可。
整个规约对本身来讲都挺有用的,由于正好涉及到这方面,幸亏感受脸不怎么疼。
浏览了一遍,仍是学习到了不少东西吧,上面也仅仅只是总结了对我本身比较收益,现阶段我能吸取能实际感觉获得的规约,若是想要 PDF 版的能够在这里下载:戳这里
欢迎转载,转载请注明出处!
简书ID:@我没有三颗心脏
github:wmyskxz 欢迎关注公众微信号:wmyskxz_javaweb 分享本身的Java Web学习之路以及各类Java学习资料