java 开发规约_阿里Java开发规约(1)

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

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

Negative example:

List list = new ArrayList();

list.add("22");

//warn

List test = (ArrayList) list.subList(0, 1);

Positive example:

List list2 = new ArrayList(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 classDemoDO{

Boolean success;

Boolean delete;

}

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

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

public class ToStringDemo extendsSuper{

privateString secondName;

@Override

publicString toString() {

return super.toString() + "ToStringDemo{" + "secondName='" + secondName + '\'' + '}';

}

}

classSuper {

privateString firstName;

@Override

publicString 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";

publicString getFormat(Date date){

SimpleDateFormat dateFormat = newSimpleDateFormat(FORMAT);

returnsdf.format(date);

}

Positive example 2:

private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public voidgetFormat(){

synchronized(sdf){

sdf.format(newDate());

….;

}

Positive example 3:

private static final ThreadLocal DATE_FORMATTER = new ThreadLocal() {

@Override

protectedDateFormat 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 staticLong readFileLength(String fileName) {

try{

File file = newFile(fileName);

RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");

returnrandomAccessFile.length();

} catch(Exception e) {

logger.error(e.getMessage(), e);

} finally{

countDownLatch.countDown();

return 0L;

}

}

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

注:会造成异常

Negative example:

List originList = new ArrayList();

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 implementsUserService {

@Override

public voidsave(User user) {

//some code

//db operation

}

}

Positive example 2:

/**

* @author caikang

* @date 2017/04/07

*/@Service

public class UserServiceImpl implementsUserService {

@Override

@Transactional(rollbackFor = Exception.class)

public voidsave(User user) {

//some code

//db operation

}

}

Positive example 3:

/**

* @author caikang

* @date 2017/04/07

*/@Service

public class UserServiceImpl implementsUserService {

@Autowired

privateDataSourceTransactionManager transactionManager;

@Override

@Transactional

public voidsave(User user) {

DefaultTransactionDefinition def = newDefaultTransactionDefinition();

// 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);

throwex;

}

}

}

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

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

/**

* @author caikang

* @date 2017/04/07

*/

public classCountDownExample {

public voidoperate(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 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 classDemoDO {

String str;

Integer a;

}

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

ThreadFactory namedThreadFactory = newThreadFactoryBuilder()

.setNameFormat("demo-pool-%d").build();

ExecutorService singleThreadPool= new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(1024), namedThreadFactory, newThreadPoolExecutor.AbortPolicy());

singleThreadPool.execute(()->System.out.println(Thread.currentThread().getName()));

singleThreadPool.shutdown();public class TimerTaskThread extendsThread {publicTimerTaskThread(){super.setName("TimerTaskThread"); …

}

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值