编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> Java -> 读书笔记 之 《阿里巴巴Java开发手册》 -> 正文阅读

[Java]读书笔记 之 《阿里巴巴Java开发手册》

一、前言
这本书主要定义了一些代码的规范以及一些注意事项。我只根据我自己的不足,摘录了一些内容,方便以后查阅。
二、读书笔记
命名
1、代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
2、常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
3、抽象类命名使用 Abstract 或 Base 开头; 异常类命名使用 Exception 结尾; 测试类命名以它要测试的类的名称开始,以 Test 结尾。
4、中括号是数组类型的一部分,数组定义如下: String[] args;
5、POJO 类中布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。
反例: 定义为基本数据类型 Boolean isDeleted; 的属性,它的方法也是 isDeleted()。 RPC框架在反向解析的时候, “以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。
6、包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
7、如果使用到了设计模式,建议在类名中体现出具体模式。有利于阅读者快速理解架构设计思想。
8、接口类中的方法和属性不要加任何修饰符号(public 也不要加) ,保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。
9、枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。
说明: 枚举其实就是特殊的常量类,且构造方法默认强制为私有。
正例: 枚举名字: DealStatusEnum, 成员名称: SUCCESS / UNKOWN_REASON。
10、各层命名规约:
A) Service/DAO 层方法命名规约
1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save(推荐) 或 insert 做前缀。
5) 删除的方法用 remove(推荐) 或 delete 做前缀。
6) 修改的方法用 update 做前缀。
B) 领域模型命名规约
1) 数据对象: xxxDO, xxx 即为数据表名。
2) 数据传输对象: xxxDTO, xxx 为业务领域相关的名称。
3) 展示对象: xxxVO, xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
常量定义
1、不允许任何未经定义的常量直接出现在代码中。
反例: String key = "Id#taobao_" + tradeId;
cache.put(key, value);
2、long 或者 Long 初始赋值时,必须使用大写的 L,不能是小写的 l,小写容易跟数字1 混淆,造成误解。
3、不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类: CacheConsts 下; 系统配置相关的常量放在类: ConfigConsts 下。
OOP规约
1、避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
2、外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么。
3、不能使用过时的类或方法。
4、Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用
equals
正例: "test".equals(object);
反例: object.equals("test");
5、所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。对于 Integer var = ? 在-128 至 127 范围内的赋值, Integer 对象是在IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
6、关于基本数据类型与包装数据类型的使用标准如下:
1) 【强制】 所有的 POJO 类属性必须使用包装数据类
2) 【强制】 RPC 方法的返回值和参数必须使用包装数
3) 【推荐】 所有的局部变量使用基本数据类型。
说明:用基本数据类型数据默认值是0,而包装数据类型默认值是null,数据库的查询结果可能为null,因为自动拆箱,用基本数据类型接收有NPE风险。
7、定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值(在数据提取时并没有置入具体值,在更新其它字段时又附带更新了此字段,导致创建时间被修改成当前时间。)
8、序列化类新增属性时,请不要修改 serialVersionUID 字段,避免反序列失败; 如果完全不兼容升级,避免反序列化混乱,那么请修改 serialVersionUID 值。注意 serialVersionUID 不一致会抛出序列化运行时异常。
9、构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。
10、类内方法定义顺序依次是:公有方法或保护方法 > 私有方法 > getter/setter方法。
11、循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
12、慎用 Object 的 clone 方法来拷贝对象。对象的 clone 方法默认是浅拷贝,若想实现深拷贝需要重写 clone 方法实现属性对象的拷贝。
13、工具类不允许有 public 或 default 构造方法。
集合处理
1、ArrayList的subList结果不可强转成ArrayList,否则会抛出 ClassCastException异常: java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
2、在 subList 场景中, 高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生 ConcurrentModificationException 异常。
3、使用集合转数组的方法,必须使用集合的 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 错误
4、使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
说明: asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
5、泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用 add 方法, 而<? super T>不能使用 get 方法,做为接口调用赋值时易出错。
说明: 扩展说一下 PECS(Producer Extends Consumer Super)原则: 1) 频繁往外读取内容的,适合用上界 Extends。 2) 经常往里插入的,适合用下界 Super。
6、不要在 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);
}
}

7、集合初始化时, 指定集合初始值大小。
说明: HashMap 使用 HashMap(int initialCapacity) 初始化,
正例:initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即 loaderfactor) 默认为 0.75, 如果暂时无法确定初始值大小, 请设置为 16。
9、使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。
说明: keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出key 所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,使用 Map.foreach 方法。
正例: values()返回的是 V 值集合,是一个 list 集合对象; keySet()返回的是 K 值集合,是一个 Set 集合对象; entrySet()返回的是 K-V 值组合集合。
10、高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:
Hashtable 不允许为 null 不允许为 null Dictionary 线程安全 ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 分段锁技术 TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全 HashMap 允许为 null 允许为 null AbstractMap 线程不安全
反例: 由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上,存储 null 值时会抛出 NPE 异常。
控制语句
1、在 if/else/for/while/do 语句中必须使用大括号。 即使只有一行代码,避免使用单行的形式: if (condition) statements;
2、表达异常的分支时, 少用 if-else 方式。如果非得使用 if()...else if()...else...方式表达逻辑,避免后续代码维护困难, 请勿超过 3 层。
3、除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。

正例:
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
...
}
反例:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
...
}

异常处理
1、Java 类库中定义的一类 RuntimeException 可以通过预先检查进行规避,而不应该通过 catch 来处理,比如: IndexOutOfBoundsException, NullPointerException 等等。
正例: if (obj != null) {...}
反例: try { obj.method() } catch (NullPointerException e) {...}
2、异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
3、有 try 块放到了事务代码中, catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
4、不能在 finally 块中使用 return, finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
5、防止空指针异常,是程序员的基本修养。
6、避免出现重复的代码(Don’t Repeat Yourself) ,即 DRY 原则。
说明: 随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是共用模块。
其他
1、在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
说明: 不要在方法体内定义: Pattern pattern = Pattern.compile(规则);
2、后台输送给页面的变量必须加$!{var}——中间的感叹号。
说明: 如果 var=null 或者不存在,那么${var}会直接显示在页面上。
3、不要在视图模板中加入任何复杂的逻辑。
说明: 根据 MVC 理论,视图的职责是展示,不要抢模型和控制器的活。
4、任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
5、对于“明确停止使用的代码和配置”,如方法、变量、类、配置文件、动态配置属性等要坚决从程序中清理出去,避免造成过多垃圾。
更新中,未完... 
书籍链接: 阿里巴巴Java开发手册
  Java 最新文章
初入山门,需记门规
java 操作本地数据库 mysql
spring boot 整合 mybatis
单表(SSM、SpringBoot、SpringCloud、Free
Mybatis框架中Mapper动态代理方式
IDEA报错:Error starting ApplicationCont
JDK源码之String、StringBuffer、StringBui
java 初始化与清理
Java 对象初始化
第四天知识点
上一篇文章      下一篇文章      查看所有文章
加:2017-08-28 23:22:35  更:2017-08-28 23:22:59 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 龙发科技 开发 中国文化 阅读网 日历 万年历 2020年10日历
2020-10-27 8:40:40
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识