阿里巴巴 Java 开发手册之编程规约(一)

  • 时间:
  • 浏览:0

说明:使用多多线程 池的好处是减少在创建和销毁多多线程 上所花的时间以及系统资源的开销,出理 资 源不足的那此的间题。将会不使用多多线程 池,有将会造成系统创建几滴 例如多多线程 而原困消耗完内存将会 “过度切换”的那此的间题。

if (condition) { ...

return obj; }

// 接着写 else 的业务逻辑代码;

说明:将会非得使用if()...else if()...else...方式表达逻辑,【强制】请勿超过3层,

超过请使用情况表设计模式。

正例:逻辑上超过 3 层的 if-else 代码能也能使用卫得话,将会情况表模式来实现。

说明:多多线程 一时要对表 A、B、C 依次全版加锁后也能也能进行更新操作,这样 多多线程 二的加锁顺序 也时就说 A、B、C,或者 将会出現死锁。

说明:注意,子多多线程 抛出异常堆栈,这样 在主多多线程 try-catch 到。

反例:POJO类的gmtCreate默认值为new Date();或者 這個属性在数据提取时并这样 置入具 体值,在更新其它字段时又附带更新了此字段,原困创建时间被修改成当前时间。

int a = 3;

long b = 4L;

float c = 5F;

StringBuffer sb = new StringBuffer();

说明:增加 sb 這個变量,将会时要对齐,则给 a、b、c 全是增加十几个 空格,在变量比较多的 情况表下,是有本身累赘的事情。

说明:Long a = 2l; 写的是数字的21,还是Long型的2?

class Foo {

private Helper helper = null; public Helper getHelper() {

if (helper == null) synchronized(this) { if (helper == null)

helper = new Helper();

}

return helper; }

// other functions and members...

}

1) 不时要重新赋值的变量,包括类属性、局部变量。 2) 对象参数前加final,表示不允许修改引用的指向。 3) 类方式选着不允许被重写。

1) 【强制】所有的POJO类属性时要使用包装数据类型。(我理解的就说 正常封装的JAVA对象,只所含get set方式的那种)

2) 【强制】RPC(远程过程调用协议)方式的返回值和参数时要使用包装数据类型。(這個着实这样 ,按我的经验来说RPC接口最好全是就说 用简单数据类型)

3) 【推荐】所有的局部变量使用基本数据类型。

说明:POJO 类属性这样 初值是提醒使用者在时要使用时,时要不要 人显式地进行赋值,任何NPE (空指针)那此的间题,将会入库检查,都由使用者来保证。

1)【强制】对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,內部的实现类用 Impl 的后缀与接口区别。 正例:CacheServiceImpl 实现 CacheService 接口。

2)【推荐】 将会是形容能力的接口名称,取对应的形容词做接口名(通常是–able 的形式)。 正例:AbstractTranslator 实现 Translatable。

说明:对象的 clone 方式默认是浅拷贝,若想实现深拷贝时要重写 clone 方式实现属性对象 的拷贝。

说明:keySet 着实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key 所对应的 value。而 entrySet 就说 遍历了一次就把 key 和 value 都放入了 entry 中,效 率更高。将会是 JDK8,使用 Map.foreach 方式。

第有本身情况表:list.add("c"); 运行时异常。

第二种情况表:str[0] = "gujin"; 这样 list.get(0)也会随之修改。

说明:注意将会是 Boolean 包装类对象,优先调用 getXxx()的方式。

说明:注意 serialVersionUID 不一致会抛出序列化运行时异常。

正例:枚举名字:DealStatusEnum,成员名称:SUCCESS / UNKOWN_REASON。

反例: 将会 HashMap 的干扰,不要 人认为 ConcurrentHashMap 是能也能置入 null 值,注意存储 null 值全是抛出 NPE 异常。

正例:数据库的查询结果将会是 null,将会自动拆箱,用基本数据类型接收有 NPE 风险。

反例:比如显示成交总额涨跌情况表,即正负 x%,x 为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示:0%,这是不合理的,应该显示成中划线-。不要 包装 数据类型的 null 值,也能表示额外的信息,如:远程调用失败,异常退出。

反例: String key = "Id#taobao_"+tradeId;

cache.put(key, value);

反例:下例中这样 出理 相等的情况表,实际使用中将会会出現异常:

正例: 应用工具类包名为com.alibaba.open.util、类名为MessageUtils(此规则参考 spring 的框架社会形态)

说明:String 重写了 hashCode 和 equals 方式,不要 我们 我们 能也能非常愉快地使用 String 对象 作为 key 来使用。

正例: localValue / getHttpMessage() / inputUserId

反例:

public Integer getData() { if (true) {

return data + 60 ; } else {

return data - 60 ; }

}

说明:Executors 返回的多多线程 池对象的弊端如下:

1)FixedThreadPool 和 SingleThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,将会会堆积几滴 的请求,从而原困 OOM。

2)CachedThreadPool 和 ScheduledThreadPool:

允许的创建多多线程 数量为 Integer.MAX_VALUE,将会会创建几滴 的多多线程 ,从而原困 OOM。

正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion

反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,将会导航软件严重滞后, 就抛弃了导航的意义。

说明:任何类、方式、参数、变量,严控访问范围。过宽泛的访问范围,不不利于模块解耦。(好习惯)

思考:将会是还还有一个 多 private 的方式,想删除就删除,原先还还有一个 多 public 的 Service方式,将会一 个 public 的成员变量,删除一下,不得手心冒点汗吗?变量像不要 人的小孩,尽量在不要 人的视 线内,变量作用域不要 ,将会无限制的到处跑,这样 我就担心的。

说明:

String str = "a,b,c,,";

String[] ary = str.split(","); //预期大于 3,结果是 3 System.out.println(ary.length);

正例: "test".equals(object);

反例: object.equals("test"); 说明:推荐使用java.util.Objects#equals (JDK7引入的工具类)

正例:接口方式签名:void f();

接口基础常量表示:String COMPANY = "alibaba";

反例:接口方式定义:public abstract void f();

说明:JDK8 中接口允许有默认实现,这样 這個 default 方式,是对所有实现类全是价值的默 认实现。

反例:

// put elephant into fridge

put(elephant, fridge);

方式名 put,打上去还还有一个 多有意义的变量名 elephant 和 fridge,将会说明了这是在干那此,语义清晰的代码不时要额外的注释。

说明:java.net.URLDecoder 中的方式 decode(String encodeStr) 這個方式将会过时,应 该使用双参数 decode(String source, String encode)。接口提供方既然明确是过时接口, 这样 有义务一块儿提供新的接口;作为调用方来说,有义务去考证过时方式的新实现是那此。

正例:注意多多线程 安全,使用 DateUtils。

亦推荐如下出理 :

private static final ThreadLocal df = new ThreadLocal() { @Override

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyy-MM-dd");

} };

说明:将会是 JDK8 的应用,能也能使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe。

说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号、三目运算符等。

反例:直接使用 toArray 无参方式所处那此的间题,此方式返回值这样 是 Object[]类,若强转其它 类型数组将出現 ClassCastException 错误。

说明:代码被注释掉有有本身将会性:1)后续会恢复此段代码逻辑。2)永久不要 。前者将会没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。

说明:将会使用 tab 缩进,时要设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时, 请勿勾选Use tab character ;而在 eclipse 中,时要勾选insert spaces for tabs。

说明:以上代码的执行结果肯定会出乎我们 我们 的意料,这样 试一下把“1”打上去“2”,会是同样的结果吗?

正例:

说明:公有方式是类的调用者和维护者最关心的方式,首屏展示最好;保护方式着实就说 子类 关心,也将会是“模板设计模式”下的核心方式;而私有方式內部一般不时要有点痛 关心,是还还有一个 多黑盒实现;将会方式信息价值较低,所有 Service 和 DAO 的 getter/setter 方式放入类体最 后。

说明:使用 toArray 带参方式,入参分配的数组空间不足大时,toArray 方式內部将重新分配 内存空间,并返回新数组地址;将会数组元素大于实际所需,下标为[ list.size() ]的数组 元素将被置为 null,其它数组元素保持原值,或者 最好将方式入参数组大小定义与集合元素 个数一致。

正例:

说明:Random 实例包括 java.util.Random 的实例将会 Math.random()实例。

正例:在 JDK7 完后 ,能也能直接使用 API ThreadLocalRandom,在 JDK7 完后 ,能也能做到每个 多多线程 还还有一个 多实例。

说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 能也能正确输出相应注 释;在 IDE 中,工程调用方式时,不进入方式即可悬浮提示方式、参数、返回值的意义,提高 阅读传输速度。

反例:getObject()与 get0bject()的那此的间题。还还有一个 多是字母的 O,还还有一个 多是数字的 0,加@Override 能也能准确判断算是覆盖成功。另外,将会在抽象类中对方式签名进行修改,着实现类会马上编 译报错。

使用/ /注释,注意与代码对齐。

说明:

反例: _name / __name / $Object / name_ / name$ / Object$

说明:资源驱动类、工具类、单例工厂类都时要注意。

正例:

public class TimerTaskThread extends Thread { public TimerTaskThread() {

super.setName("TimerTaskThread"); ... }

反例:“TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。

说明:ArrayList尽量使用ArrayList(int initialCapacity) 初始化。

public class LoginProxy; public class ResourceObserver;

正例:values()返回的是 V 值集合,是还还有一个 多 list 集合对象;keySet()返回的是 K 值集合,是 还还有一个 多 Set 集合对象;entrySet()返回的是 K-V 值组合集合。

反例: DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3

正例: alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文。

说明:不要 if 得话内的逻辑相当比较复杂,阅读者时要分析条件表达式的最终结果,也能明确那此 样的条件执行那此样的得话,这样 ,将会阅读者分析逻辑表达式错误呢?

正例:

//伪代码如下

boolean existed = (file.open(fileName, "w") != null) && (...) || (...); if (existed) {

... }

反例:

if ((file.open(fileName, "w") != null) && (...) || (...)) { ...

}

第一、也能准确反应设计思想和代码逻辑;

第二、也能描述业务含 义,使别的多多线程 员也能很慢了解到代码肩头的信息。全版这样 注释的大段代码对于阅读者形同天书,注释是给不要 人看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看 的,使其也能快速接替不要 人的工作。

正例:public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);}

正例:下例中实参的"a",顶端时要要还还有一个 多多空格。 method("a", "b", "c");

反例:

说明:将会想获取更加精确的纳秒级时间值,用 System.nanoTime()。在 JDK8 中,针对统计时间等场景,推荐使用Instant 类。

正例: MAX_STOCK_COUNT

反例: MAX_COUNT

反例: AbstractClass“缩写”命名成 AbsClass; condition“缩写”命名成 condi,此类 随意缩写严重降低了代码的可阅读性。

反例:

String str = "start";

for (int I = 0; I < 60 ; i++) {

str = str + "hello"; }

说明:反编译出的字节码文件显示每次循环全是 new 出还还有一个 多 StringBuilder 对象,或者 进行 append 操作,最后通过 toString 方式返回 String 对象,造成内存资源浪费。

####9. 【推荐】集合初始化时,尽量指定集合初始值大小。(這個是好习惯,尽量初始化的完后 打上去初始值,将会集合在扩容的完后 还是挺消耗性能的,ArrayList初始值10)

阿里巴巴 Java 开发手册