Java开发规范总结(两周至少看一次)
Service / DAO 层方法命名规约:
1 ) 获取单个对象的方法用 get 做前缀。
2 ) 获取多个对象的方法用 list 做前缀。
3 ) 获取统计值的方法用 count 做前缀。
4 ) 插入的方法用 save( 推荐 ) 或 insert 做前缀。
5 ) 删除的方法用 remove( 推荐 ) 或 delete 做前缀。
6 ) 修改的方法用 update 做前缀。
领域模型命名规约:
1 ) 数据对象: xxxDO , xxx 即为数据表名。
2 ) 数据传输对象: xxxDTO , xxx 为业务领域相关的名称。
3 ) 展示对象: xxxVO , xxx 一般为网页名称。
4 ) POJO 是 DO / DTO / BO / VO 的统称,禁止命名成 xxxPOJO 。
常量定义:
1)不允许任何魔法值 ( 即未经定义的常量 ) 直接出现在代码中。反例: String key = " Id # taobao _" + tradeId
2)不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类: CacheConsts 下 ; 系统配置相关的常量放在类: ConfigConsts 下。说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。
3)如果变量值仅在一个范围内变化,且带有名称之外的延伸属性,定义为枚举类。下面正例中的数字就是延伸信息,表示星期几。正例: public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6),SUNDAY(7);}
代码格式:
1) 左小括号和字符之间不出现空格 ; 同样,右小括号和字符之间也不出现空格。详见第 5 条下方正例提示。反例: if (空格 a == b 空格)
2) if / for / while / switch / do 等保留字与括号之间都必须加空格。
3) 任何二目、三目运算符的左右两边都需要加一个空格。说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号等。
4) 单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
1) 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
2 ) 运算符与下文一起换行。
3 ) 方法调用的点符号与下文一起换行。
4 ) 在多个参数超长,在逗号后换行。
5 ) 在括号前不要换行,见反例。
正例:
StringBuffer sb = new StringBuffer();
//超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点符号一起换行
sb.append("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");
5) 方法参数在定义和传入时,多个参数逗号后边必须加空格。正例:下例中实参的" a ",后边必须要有一个空格。method("a", "b", "c");
OOP约束:
1) 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
2) 所有的覆写方法,必须加@ Override 注解。说明: getObject() 与 get 0 bject() 的问题。一个是字母的 O ,一个是数字的 0,加@ Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。
3)相同参数类型,相同业务含义,才可以使用 Java 的可变参数,避免使用 Object 。说明:可变参数必须放置在参数列表的最后。 ( 提倡同学们尽量不用可变参数编程 )正例: public User getUsers(String type, Integer... ids) {...}
4)Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals 。正例: " test " .equals(object);反例: object.equals( " test " );说明:推荐使用 java . util . Objects # equals (JDK 7 引入的工具类 )
5) 关于基本数据类型与包装数据类型的使用标准如下:【强制】所有的 POJO 类属性必须使用包装数据类型。【强制】 RPC 方法的返回值和参数必须使用包装数据类型。【推荐】所有的局部变量使用基本数据类型。
6) 【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
说明:反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行
append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。
反例:
String str = "start";
for (int i = 0; i < 100; i++) {
str = str + "hello";
}
集合处理:
1. 【强制】关于 hashCode 和 equals 的处理,遵循如下规则:1) 只要重写 equals ,就必须重写 hashCode 。
2) 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法。
3) 如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals 。说明: String 重写了 hashCode 和 equals 方法,所以我们可以非常愉快地使用 String 对象作为 key 来使用。
2. 【强制】 ArrayList 的 subList 结果不可强转成 ArrayList ,否则会抛出 ClassCastException异常: java . util . RandomAccessSubList cannot be cast to java . util . ArrayList ;
说明: subList 返回的是 ArrayList 的内部类 SubList ,并不是 ArrayList ,而是ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
3. 【强制】 在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生 ConcurrentModificationException 异常。
4. 【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array) ,传入的是类型完全一样的数组,大小就是 list . size() 。说明:使用 toArray 带参方法,入参分配的数组空间不够大时, toArray 方法内部将重新分配
内存空间,并返回新数组地址 ; 如果数组元素大于实际所需,下标为 [ list . size() ] 的数组元素将被置为 null ,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素个数一致。
正例:
List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);
反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[] 类,若强转其它类型数组将出现 ClassCastException 错误。
5. 【强制】使用工具类 Arrays . asList() 把数组转换成集合时,不能使用其修改集合相关的方法,它的 add / remove / clear 方法会抛出 UnsupportedOperationException 异常。说明: asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。 Arrays . asList
体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一种情况: list.add("c"); 运行时异常。
第二种情况: str[0] = "gujin"; 那么 list.get(0) 也会随之修改。
6. 【强制】泛型通配符<? extends T >来接收返回的数据,此写法的泛型集合不能使用 add 方法,而 <? super T> 不能使用 get 方法,做为接口调用赋值时易出错。说明:扩展说一下 PECS(Producer Extends Consumer Super) 原则:1)频繁往外读取内容
的,适合用上界 Extends 。2)经常往里插入的,适合用下界 Super 。
7. 【强制】不要在 foreach 循环里进行元素的 remove / add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。
正例:
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String temp = it.next();
if (删除元素的条件) {
it.remove();
}
}
反例:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if ("1".equals(temp)) {
a.remove(temp);
}
}
说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?
8. 【强制】 在 JDK 7 版本及以上, Comparator 要满足如下三个条件,不然 Arrays . sort ,Collections . sort 会报 IllegalArgumentException 异常。
说明:
1 ) x , y 的比较结果和 y , x 的比较结果相反。
2 ) x > y , y > z ,则 x > z 。
3 ) x = y ,则 x , z 比较结果和 y , z 比较结果相同。
反例:下例中没有处理相等的情况,实际使用中可能会出现异常:
new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() > o2.getId() ? 1 : -1;
}
};
9. 【推荐】集合初始化时,指定集合初始值大小。说明: HashMap 使用 HashMap(int initialCapacity) 初始化,正例: initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader
factor)默认为 0.75, 如果暂时无法确定初始值大小,请设置为 16。反例: HashMap 需要放置 1024 个元素,由于没有设置容量初始大小,随着元素不断增加,容量 7 次被迫扩大, resize 需要重建 hash 表,严重影响性能。
10. 【推荐】使用 entrySet 遍历 Map 类集合 KV ,而不是 keySet 方式进行遍历。说明: keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出key 所对应的 value 。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效
率更高。如果是 JDK 8,使用 Map . foreach 方法。正例: values() 返回的是 V 值集合,是一个 list 集合对象 ;keySet() 返回的是 K 值集合,是一个 Set 集合对象 ;entrySet() 返回的是 K - V 值组合集合。
11. 【推荐】高度注意 Map 类集合 K / V 能不能存储 null 值的情况,如下表格:集合类 集合类 Key Value Super 说明 说明
Hashtable 不允许为 null 不允许为 null Dictionary 线程安全
ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 分段锁技术
TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全
HashMap 允许为 null 允许为 null AbstractMap 线程不安全
反例: 由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上,存储 null 值时会抛出 NPE 异常。
12. 【参考】合理利用好集合的有序性 (sort) 和稳定性 (order) ,避免集合的无序性 (unsort) 和不稳定性 (unorder) 带来的负面影响。说明:有序性是指遍历的结果是按某种比较规则依次排列的。稳定性指集合每次遍历的元素次
序是一定的。如: ArrayList 是 order / unsort;HashMap 是 unorder / unsort;TreeSet 是order / sort 。
13. 【参考】利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、去重操作。
Java开发规范总结(两周至少看一次)的更多相关文章
- eclipse安装阿里巴巴java开发规范插件
阿里巴巴java开发规范插件 作为JAVA开发人员,始终没有一个明确的规范,何为好代码,何为坏代码,造成不同人的代码风格不同,接手别人代码后改造起来相当困难.前不久,阿里巴巴发布了<阿里巴巴Ja ...
- myeclipse 阿里巴巴java开发规范
今天发现阿里巴巴搞了个java开发规范,然后火了: 然后发现我也整了一下: 阿里巴巴java开发规范宣传页: http://mp.weixin.qq.com/s/IbibsXlWHlM59kfXJqR ...
- 阿里Java开发规范&谷歌Java开发规范&华为Java开发规范&Tab键和空格比较&Eclipse的Tab键设置 总结
现在收集到如下有用的信息: 阿里巴巴公开的Java开发规范:https://yq.aliyun.com/articles/69327?utm_content=m_10088 google公开的Java ...
- 阿里巴巴Java开发规范手册
Java开发手册 版本号 制定团队 更新日期 备 注 1.0.0 阿里巴巴集团技术部 2016.12.7 首次向Java业界公开 一.编程规约 (一) 命名规约 1. [强制]所有编程相关命 ...
- 阿里java开发规范学习(附P3C IDEA插件 帮助规范的养成)
浅析 阿里巴巴 Java 开发规约 (未完成) 更加优秀的页面展现请到浅析 阿里巴巴 Java 开发规约 contents 为什么要学 编程规约 P3C IDEA 插件 why-use 我们知道,一般 ...
- 阿里Java开发规范记录(一)
近日,从网上下载了阿里云栖社区发布的<阿里巴巴Java开发手册(正式版)>v1.1.0版.从编程以来,一直苦于没有相关的.全面的.靠谱的规范可以参考,有了这手册,日后编程也算是找到了依 ...
- 一份完整的 MySQL 开发规范,进大厂必看!
作者:听风 https://www.cnblogs.com/huchong/p/10219318.html 一.数据库命令规范 1.所有数据库对象名称必须使用小写字母并用下划线分割 2.所有数据库对象 ...
- 我的java开发规范
关于文件的命名参考阮一峰的这篇文章:http://www.ruanyifeng.com/blog/2017/02/filename-should-be-lowercase.html,文中说文件名全部使 ...
- Google的Java开发规范
长期以来,Google一直有针对各种语言的规范,例如C++, Python等等.惟独对于Java语言,Google一直没有给出相应的规范(传说中是因为Google Java首席构架师Joshua Bl ...
随机推荐
- php Yii2图片的url自动加localhost
解决方法:在地址前加http://,这样url就是绝对地址,不加的话是相对地址,游览器会自动转换,即加localhost
- 介绍maven构建的生命周期
介绍maven构建的生命周期 这篇是 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 的 ...
- LaTeX的图片插入及排版
LaTeX中一般只直接支持插入eps(Encapsulated PostScript)格式的图形文件, 因此在图片插入latex文档之前应先设法得到图片的eps格式的文件. UNIX下的各种应用软件都 ...
- GHO2VMDK转换工具分享含VS2010源码
平常经常用到虚拟机,每次从gho转换为vmdk时都要输入cmd代码,觉得麻烦,自己动手做了个gho2vmdk转换工具,集成ghost32.exe文件,可以一键转换,省时省事.运行时会将ghost32. ...
- JSP编译指令与动作指令
下面这个面试经常问到,要理解. 上面这个效果一样,重点. <jsp:include>动作在请求期间被执行,而include指令在编译期页面间被执行.
- MySQL插入、更新、删除数据
1.插入数据:由于下表的id会自增,故赋值null. 注意:字符串用' '单引号,不能双引号,英文状态下. 可以写上部分属性名进行插入操作,如bookTypeId没写,默认NULL. 也可以写上所 ...
- 求最长公共前缀和后缀—基于KMP的next数组
KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如 LeetCode的shortest ...
- [2012-05-31]awk去重复项
参考http://bbs.chinaunix.net/thread-2309494-1-1.html 10.awk '! a[$0]++' 怎么理解? 这是一个非常经典的去重复项的awk语句,虽然短小 ...
- GreenOpenPaint简介
一.项目概述 类似Windows系统下面的画图程序,但是已经从底层全部重新实现,改造成为"图像处理"类程序的基本运行框架. 由于是demo界面,较为简陋,但是因为框架已经搭建完善, ...
- 在JS事件封装时,addEventListener()方法的this问题
最近在写js的类库,模仿的是jquery的编程风格,当封装到事件监听的时候发现遇到了一个问题,代码是这样的: 上面是封装的一个事件委托的代码,我以为上面的封装跟普通的事件监听一样简单,结果我在调用时发 ...