1. 创业小能手网首页
  2. 创业贷款
国家反诈骗中心app下载

[阿里巴巴贷款]阿里巴巴编码规范(Java)证明

来源丨编程一生背景阿里云上有个阿里巴巴编码规范认证,我估算一下时间成本很低,多个认证也没什么坏处,就花了1分钱报了个名。这个认证报名后就可以下载链接下的编码规范,然后参加个考试应该就OK了。共48页的规范实际上每读一遍都是要花一些时间的,因为每读一遍就会发现上面有些东西

来源丨编程一生

背景

阿里云上有个阿里巴巴编码规范认证,我估算一下时间成本很低,多个认证也没什么坏处,就花了1分钱报了个名。这个认证报名后就可以下载链接下的编码规范,然后参加个考试应该就OK了。

共48页的规范实际上每读一遍都是要花一些时间的,因为每读一遍就会发现上面有些东西我不信。我需要去证明。过去证明过的因为JDK版本升级迭代有可能需要继续证明。下面是其中的一些证明过程。

案例1

规范原文

【强制】不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作需要对Iterator对象加锁。

正例:

List list=new ArrayList<>;

list.add(“1”);

list.add(“2”);

Iterator iteraot=list.interator;

while(iterator.hasNext){

String item=iterator.next;

if(删除元素的条件) {

iterator.remove;

}

}

反例:

for(String item : list) {

if(“1”.equals(item)) {

list.remove(item);

}

}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把”1″换成”2″,会是同样的结果吗?

证明

1.先按照反例例文运行测试(test1)

list里两个元素,remove掉一个,剩下1个。这应该是符合大多数人预期的。

2.按照说明把”1″换成”2″运行测试(test2)

这里没有按照预期remove掉”2″,而是抛出了并发修改异常。点击到异常的地方

3.根据异常提示。找到抛出异常代码的地方查看是哪个方法抛出异常:

4.对源码做一个解析:

抛出并发修改异常的条件是modCount!=expectedModCount。

5.根据这个条件,我做一个推测:在一个操作里把这两者的值改的不一样了,因为这里调用了remove修改方法。我自然就推测是remove方法做的修改,来看remove方法的源码:

6.果然,源码中将modCount++,但是expectedModCount并没有修改。证明了推测。运行完remove后需要判断for(String item : list) ,这时候调用了迭代器的next方法。这样我理解了上面test2里为什么会抛出异常。那么再来思考下test1为什么不抛出异常呢?

7.我们来debug一下test1的情况1

运行完remove方法后,可看到这时候modCount!=expectedModCount,但是这时候只执行了hasNext,判断了cursor !=size,这时候不会执行next方法,所以不会产生异常。而下面再用到list时迭代器是新的迭代器,会把modCount=expectedModCount;

结论

如果list在for循环里调用remove方法是会抛出并发修改异常的,但是如果只修改了第1个就返回的情况是个例外,因为这时候不会调用next方法判断modCount和expectedModCount是否相等。

使用代码规范推荐的迭代器,底层remove方法会将modCount和expectedModCount一起修改,所以单线程不会有并发问题,作为类的成员变量,多线程情况下被修改就不确定了。

思考题

下面代码的执行结果是多少?

案例2

规范原文

【强制】在JDK7版本及以上,Comparotor实现类要满足如下三个条件,不然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 Comparotor {

@Override

public int compare(Student o1, Student o2) {

return o1.getId>o2.getId?1:-1;

}

}

证明

1.我们先来看看反例在实际使用中会抛出什么异常。

2.测试发现不论是Collections.sort还是Arrays.sort都抛出错误说必须实现Comparable接口而不是Comparator接口。而Comparable接口是不需要满足规范里所说的自反性、传递性和对称性的。

那为什么规范里会这么说呢?

3.我查了Collections类的源码,确实有几个方法用到了Comparator类。包括反转、二分查找、最大值、最小值和几个sort等。后面的原来sort是可以后面接Comparator参数的。

4. 然而我用源码的两个参数形式传入后,运行了几个例子并没有抛出非法参数异常。于是我又在源码中找线索。

Collections.sort底层用了Arrays.sort,Arrays.sort底层用了TimSort,TimSort有两处会抛出这个异常,看源码是在二分查找merge结果的时候。

5.使用这个sort果然是发生了非法参数异常。

6.具体为什么会发生异常,我打了断点,使用debug跟了一下TimSort源码,大体是有部分排序使用了if(x

站长声明:本文《[阿里巴巴贷款]阿里巴巴编码规范(Java)证明》源于网络采集,文章如涉及版权问题,请及时联系管理员删除-https://www.dkgfj.cn/15197.html

联系我们

QQ:78298281

在线咨询:点击这里给我发消息

邮件:78298281@QQ.com

工作时间:9:00-23:30,节假日无休

鲁ICP备2023001282号-1

鲁公网安备 37032102000303号