本文是对阿里插件中规约的详细解释一,关于插件使用,请参考这里

1. ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常。 说明:禁止强转,如果需要用到集合特性方法,请新建一个集合,然后置入sublist,new 集合(sublist结果)。

Negative example:
List<String> list = new ArrayList<String>();
list.add("22");
//warn
List<String> test = (ArrayList<String>) list.subList(0, 1); Positive example:
List<String> list2 = new ArrayList<String>(list.subList(0, 1));

2. iBATIS自带的queryForList(String statementName,int start,int size)不推荐使用

3. long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。 (注:规约)

Negative example:
//It is hard to tell whether it is number 11 or Long 1.
Long warn = 1l; Positive example:
Long notwarn = 1L;

4. Map/Set的key为自定义对象时,必须重写hashCode和equals。

注:两个相同的对象,要求hashcode必须相同,但反之无此要求。因为用hashcode的本意在于提高效率,
所以有时在比较对象时(比如map的contain等),会先比较hashcode,如果hashcode不等,就直接返回结果
关于hashCode和equals的处理,遵循如下规则:  
1) 只要重写equals,就必须重写hashCode。  
2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。  
3) 如果自定义对象作为Map的键,那么必须重写hashCode和equals。

5. Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。

6. POJO类中的任何布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误

public class DemoDO{
Boolean success;
Boolean delete;
}

7. POJO类必须写toString方法。(约定)

使用工具类source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。 说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。

public class ToStringDemo extends Super{
private String secondName; @Override
public String toString() {
return super.toString() + "ToStringDemo{" + "secondName='" + secondName + '\'' + '}';
}
} class Super {
private String firstName; @Override
public String toString() {
return "Super{" + "firstName=" + firstName + '\'' + '}';
}
}

8. SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。

说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat,
官方给出的解释:simple beautiful strong immutable thread-safe。 Positive example 1:
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
public String getFormat(Date date){
SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
return sdf.format(date);
} Positive example 2:
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void getFormat(){
synchronized (sdf){
sdf.format(new Date());
….;
} Positive example 3:
private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};

9. 不允许任何魔法值(即未经定义的常量)直接出现在代码中

Negative example:
//Magic values, except for predefined, are forbidden in coding.
if(key.equals("Id#taobao_1")){
//...
} Positive example:
String KEY_PRE = "Id#taobao_1";
if(key.equals(KEY_PRE)){
//...
}

10. 不能使用过时的类或方法。

说明:java.net.URLDecoder 中的方法decode(String encodeStr) 这个方法已经过时,应该使用双参数decode(String source, String encode)。
接口提供方既然明确是过时接口,那么有义务同时提供新的接口;作为调用方来说,有义务去考证过时方法的新实现是什么。

11. 不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。

注:这里阿里没有解释清楚,其实指的是如果try中语句出现异常,因为finally的return语句,会造成异常丢失的情况

Negative example:
public static Long readFileLength(String fileName) {
try {
File file = new File(fileName);
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
return randomAccessFile.length();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
countDownLatch.countDown();
return 0L;
}
}

12. 不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。

注:会造成异常

 Negative example:
List<String> originList = new ArrayList<String>();
originList.add("22");
for (String item : originList) {
//warn
list.add("bb");
}

13. 中括号是数组类型的一部分,数组定义如下:String[] args  (注:约定)

14. 事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。

注:spring中@Transactional默认当抛出RuntimeException时会自动回滚

Positive example 1:
/**
* @author caikang
* @date 2017/04/07
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
//some code
//db operation
}
} Positive example 2:
/**
* @author caikang
* @date 2017/04/07
*/
@Service
public class UserServiceImpl implements UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public void save(User user) {
//some code
//db operation
}
} Positive example 3:
/**
* @author caikang
* @date 2017/04/07
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private DataSourceTransactionManager transactionManager; @Override
@Transactional
public void save(User user) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
//db operation
} catch (Exception ex) {
transactionManager.rollback(status);
throw ex;
}
}
}

15. 使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。 说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。

注:关于CountDownLatch,用于需子线程结束主线程才能继续的场景,可以参考这里

    /**
* @author caikang
* @date 2017/04/07
*/
public class CountDownExample {
public void operate(CountDownLatch countDownLatch){
try{
System.out.println("business logic");
}catch (RuntimeException e){
// do something
}finally {
countDownLatch.countDown();
}
}
}

16. 使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。

注:看Arrays.asList源码可以知道这个方法生成的是Arrays里面的一个size固定的内部类ArrayList,而不是常用的ArrayList,虽然它也实现List接口

Positive example:
List<String> t = Arrays.asList("a","b","c");
//warn
t.add("22");
//warn
t.remove("22");
//warn
t.clear();

17. 使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()

Negative example:
Integer[] a = (Integer [])c.toArray(); Positive example:
Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);

18. 关于基本数据类型与包装数据类型的使用标准如下:

 1) 所有的POJO类属性必须使用包装数据类型。
 2) RPC方法的返回值和参数必须使用包装数据类型。
 3) 所有的局部变量推荐使用基本数据类型。 说明:POJO类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何NPE问题,或者入库检查,都由使用者来保证。

注:NPE:NullPointerException,这样写是为了统一,用户显式赋值,要比有默认值为前提不容易出错

    public class DemoDO {
String str;
Integer a;
}

19. 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。

    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("demo-pool-%d").build();
ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));
singleThreadPool.shutdown(); public class TimerTaskThread extends Thread {
public TimerTaskThread(){
super.setName("TimerTaskThread"); …
}

20.  包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式

com.alibaba.mpp.util / com.taobao.tddl.domain.dto

阿里Java开发规约(1)的更多相关文章

  1. 阿里Java开发规约插件使用

    刚刚的云栖大会上,阿里巴巴公布了这款酝酿已久的Java开发规约插件,对于国内开发者来说是一次轻松提高自己代码规范的机会. 安装方法 IDEA安装方法: settings >> plugin ...

  2. 阿里Java开发规约笔记

    借助阿里开发规约,回顾一下Java开发编码基础方面的知识,结合自己使用中遇到的问题,记录一下规约中以前翻过的错.有共鸣的问题. 1.覆写方法时要加上@Override注解.重写一个类型T的equals ...

  3. 阿里Java开发规约(2)

    本文是对阿里插件中规约的详细解释二,关于插件使用,请参考这里 及时清理不再使用的代码段或配置信息. 说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余 Positive examp ...

  4. 阿里Java开发规约【摘录】

    1.命名规约 [强制]类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO等. 正例:MarcoPolo / User ...

  5. 阿里和Google的JAVA开发规约

    <阿里 JAVA开发规约> 阿里巴巴Java开发手册终极版v1.3.0.pdf 出处:github地址:https://github.com/alibaba/p3c <Google ...

  6. 为什么阿里Java规约要求谨慎使用SimpleDateFormat

    前言 在阿里Java开发规约中,有强制性的提到SimpleDateFormat 是线程不安全的类 ,在使用的时候应当注意线程安全问题,如下: 其实之前已经介绍过使用JDK1.8的DateTimeFor ...

  7. 阿里巴巴 Java 开发规约插件初体验

    阿里巴巴 Java 开发手册 又一次来谈<阿里巴巴 Java 开发手册>,经过这大半年的版本迭代,这本阿里工程师们总结出来避免写出那么多 Bug 的规范,对于 Java 开发者简直就是必备 ...

  8. 阿里巴巴Java开发规约及插件安装

    [上海尚学堂编辑整理]10.14日,阿里巴巴在杭州云栖大会上,正式发布了由阿里巴巴 P3C 项目组,经过 近一年的持续研发,正式发布众所期待的 <阿里巴巴 Java 开发规约>的扫描插件. ...

  9. 阿里java代码检测工具p3c

    阿里在杭州云栖大会上,正式发布众所期待的<阿里巴巴Java开发规约>扫描插件! 该插件由阿里巴巴P3C项目组研发.这个项目组是阿里巴巴开发爱好者自发组织形成的虚拟项目组,把<阿里巴巴 ...

随机推荐

  1. 使用广播退出打开了多个activity的程序

    新建一个父类,在父类里动态注册广播,在这个广播的onrecive方法中结束当前activity,让每个activity继承这个父类,在要关闭的activity中发送广播,搞定 下面是代码 父类 pro ...

  2. day17-jdbc 2.jdbc介绍

    SQL是一种非过程性语言,只能写一条嘛,你写多条不行嘛.每个数据库都有自己的存储过程.你可以做编程,你可以写多条SQL语句把它放到一起.这就是存储过程.然后用的时候一调它就执行这个逻辑结构了.因为多条 ...

  3. python NLTK 环境搭建

    这里是我之前亲自操作过安装nltk,安装成功了.当时记得是参考这篇博文:http://www.tuicool.com/articles/VFf6Bza 其中,nltk安装时,遇到模块未找到,依次根据提 ...

  4. css3(border-radius)边框圆角详解(转)

    css3(border-radius)边框圆角详解 (2014-05-19 16:16:29) 转载▼ 标签: divcss html it css3 分类: 网页技术 传统的圆角生成方案,必须使用多 ...

  5. sequelize 用于PostgreSQL,MySQL,SQLite和MSSQL的Node.js / io.js ORM

    安装 Sequelize可通过NPM获得. $ npm install --save sequelize # And one of the following: $ npm install --sav ...

  6. PCL — Point Pair Feature 中层次点云处理

    博客转载自:http://www.cnblogs.com/ironstark/p/5971976.html 机器人视觉中有一项重要人物就是从场景中提取物体的位置,姿态.图像处理算法借助Deep Lea ...

  7. PrototypePattern(23种设计模式之一)

    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...

  8. c++ 拷贝构造函数 继承

    拷贝构造函数要求把所有变量都需要做拷贝.在有继承关系情况先,子类的拷贝构造函数,需要调用父类拷贝构造函数.示例代码如下: class Base{ public: virtual ~Base(); Ba ...

  9. ZROI2018提高day1t3

    传送门 分析 考场上想到了先枚举p的长度,在枚举这个长度的所有子串,期望得分40~50pts,但是最终只得了20pts,这是因为我写的代码在验证中总是不断删除s'中的第一个p,而这种方式不能解决形如a ...

  10. Entity Framework Tutorial Basics(38):Explicit Loading

    Explicit Loading with DBContext Even with lazy loading disabled, it is still possible to lazily load ...