《aliJava开发规范》小结(一)

1、【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。

说明: 对于 Integer var=?在-128 至 127 之间的赋值, Integer 对象是在
IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
示例如下:

package java基础.类初始化问题;

/**
 * @Author: wangxi
 * @Description :
 * @Date: 2018/5/30 0030 20:02
 */
public class Demo03 {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        // 下面返回false,参考上述的第一条规范讲解
        System.out.println(e == f); // false
        Long g = 3L;
        System.out.println(a.intValue()); // 1
        System.out.println(c == d); // true
        System.out.println(c == (a + b)); //true
        // 所有包装类重写了equals方法。首先用了instanceof判断。
        System.out.println(c.equals(a + b)); //true
        System.out.println(g == (a + b));  //true自动拆箱,然后隐式强转
        System.out.println(g.equals(a + b)); //false
        int tem1 = 1;
        long temp2 = 1L;
        System.out.println(tem1 == temp2); // true

        /** 反编译后的代码
         * public static void main(String args[])
         {   // 返回Integer对象。注意上述的坑
             Integer a = Integer.valueOf(1);
             Integer b = Integer.valueOf(2);
             Integer c = Integer.valueOf(3);
             Integer d = Integer.valueOf(3);
             Integer e = Integer.valueOf(321);
             Integer f = Integer.valueOf(321);
             Long g = Long.valueOf(3L);
             System.out.println(a.intValue());
             System.out.println(c == d);
             System.out.println(c.intValue() == a.intValue() + b.intValue());
             System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
             System.out.println(g.longValue() == (long)(a.intValue() + b.intValue()));
             System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
         }
         */

    }

}

笔者使用了jad反编译工具非常好用。需要的小伙伴可以留言哟!

2、【推荐】循环体内,字符串的联接方式,使用 StringBuilder 的 append 方法进行扩展。

反例:
String str = “start”;
for(int i=0; i<100; i++){
str = str + “hello”;
}
说明: 反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。这样会创建很多StringBuilder对象

3、【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。

keySet 其实是遍历了 2 次,而entrySet 只遍历了一次,效率更高。

package 集合底层源码分析;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: wangxi
 * @Description :
 * @Date: 2018/8/15 0015 9:54
 */
public class Map的遍历 {
    public static void main(String[] args) {
        // 为了优化考虑,在创建ArrayList、HashMap时,指定大小。
        // 扩容元素的复制很消耗资源!
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1, 1);
        map.put(2, 2);
        map.put(3, 3);
        // 方法一:
        for (Map.Entry<Integer, Integer> m : map.entrySet()) {
            System.out.println(m);
        }
        System.out.println("=====================================");
        // 方法二 JDK1.8的方法
        map.forEach((K, V) -> System.out.println(K + ":" + V));
    }
}
内容扩展:foreach的实现原理:
public class Iterable_eros {  

    List<String> strings;  

    public void display(){  
        for(String s : strings){  
            System.out.println(s);  
        }  
    }  

}  

经过反编译后的代码如下:

public void display (){  
line0    : aload_0    
           getfield  java.util.List my.lang.Iterable_eros.strings  
           invokeinterface  java.util.Iterator java.util.List.iterator() 1  
           astore_2    
           goto  line30  
line13   : aload_2    
           invokeinterface  java.lang.Object java.util.Iterator.next() 1  
           checkcast  java.lang.String  
           astore_1    
line23   : getstatic  java.io.PrintStream java.lang.System.out  
           aload_1    
line27   : invokevirtual  void java.io.PrintStream.println(java.lang.String)  
line30   : aload_2    
           invokeinterface  boolean java.util.Iterator.hasNext() 1  
           ifne  line13  
line39   : return   

可以看到,foreach语法最终被编译器转为了对Iterator.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。

4、【推荐】高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:
集合类KeyValueSuper说明
Hashtable不允许为null不允许为nullDictionary线程安全
ConcurrentHashMap不允许为 null不允许为 nullAbstractMap分段锁技术
TreeMap不允许为 null不允许为 nullAbstractMap线程不安全
HashMap允许为 null(只有一个null键)允许为 null(有多个null值)AbstractMap线程不安全

反例: 由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,注意存储null 值时会抛出 NPE 异常。

继续更新中……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值