最近又阅读了一遍阿里的Java 开发手册,发现了一些平时没有太注意的点,特此记录下来方便平时查阅。
-
POJO 类中布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误。
eg:定义为基本数据类型 boolean isDeleted 的属性,它的方法也是isDeleted(),RPC框架在反向解析的时候,“以为”对应的属性名称是deleted,导致属性获取不到,进而抛出异常。
-
long 或者Long 初始赋值时,使用大写的 L,不能是小写的 l;小写容易跟数字1混淆,造成误解。
-
Object 的equals 方法容易抛出空指针异常,应使用常量或确定有值的对象来调用equals。
eg:”test”.equals(object);
注:可以使用java.util.Object#equals(JDK7 引入的工具类),不过在Android 中此方法只能在API19 及以上使用。
-
所有的相同类型的包装类对象之间==值的比较==,全部使用 equals 方法比较。
因为对于-128 到128 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象。因此推荐使用 equals 方法进行判断。
-
关于集合 hashcode 的处理:
a. 只要重写 equals,就必须重写hashcode。
b. 因为Set 存储的是不重复的对象,依据 hashcode 和equals 进行推断,所以 Set 存储的对象必须重写这两个方法。
-
使用工具类 Arrays.asList() 把数组转换成集合时,不能使用其修改集合相关的方法,如 add/remove/clear,会抛出UnSupportedOperationException 异常。
注:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适配器模式,只是转换接口,后台的数据仍是数组。
-
不要再foreach循环里进行元素的remove/add 操作。remove 操作使用Iterator方式,如果需要并发操作,需要对Iterator 对象加锁。
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); // for (String string : list) { // if ("2".equals(string)) { // // 不要再foreach循环里进行元素的add、remove操作 // // 运行这段代码会java.util.ConcurrentModificationException // list.remove(string); // } // } Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String string = (String) iterator.next(); if ("2".equals(string)) { iterator.remove(); } } for (String string2 : list) { System.out.println("element is-->" + string2); }
-
集合初始化时,制定集合初始值大小。
HashMap 使用HashMap(int initialCapacity) 初始化,其中
initialCapacity = (需要存储的元素个数 / loader factor) + 1,loader factor 默认值为0.75,如果暂时无法无法确定初始值大小,可以设置默认值为16。
-
HashMap 是线程不安全的,其Key 和 Value 允许为null;ConcurrentHashMap 是线程安全的,它和 HashMap 一样均继承自 AbstractMap,但是的Key,Value 则是不允许为 null 的。
-
如果 substring 方法中 index 等于0,则直接返回当前对象;如果 index 不等于0,则 new 一个 sub 的对象返回。
String str = "abc";
System.out.println("abc" == str);//打印结果结果true
System.out.println("abc" == substring(0));//打印结果结果true
System.out.println("ab".substring(1));//打印结果结果false
-
当两个字符串常量连接(相加)时,得到的依然是字符串常量并且存储在常量池中也只有一份。
String str = "strA"; String str1 = "str" + "A"; System.out.println(str == str1)//打印结果结果true
-
当一个字符串常量与一个 String 类型变量连接时,得到的新字符串不再存储在常量池中,而是在堆中新建一个 String 对象来存放。因为常量池中要求存放的是常量,有String 类型变量当然不能存储在常量池中了。
String strA = "ab"; String strB = "b"; String strC = "a" + "strB"; System.out.println(strA ==strC);//打印结果结果false