前言 findBuds真是一个好插件, 找到了许多平时都不知道的高危bug。 在我解析字符串时
1 2 3 4 @Override public long getLong (String key) { return Long.valueOf(key == null ? "0" : key.toString()); }
给我爆了这个警告
1 2 Boxing/unboxing to parse a primitive A boxed primitive is created from a String, just to extract the unboxed primitive value. It is more efficient to just call the static parseXXX method.
意思是一个包装类由字符串创建, 只是为了获取基本数据类型的值, 调用parseXxx更有效
。
两个方法的返回值不同 jdk7提供的自动拆装箱语法糖是很不错的。 但是过份依赖语法糖就会出现一些 常识性
问题。 两个方法如下
1 2 public static long parseLong(String s); public static Long valueOf(String s);
先说结论
要获取基本数据类型就使用 parseXxx
要获取包装数据类型就使用 valueOf
看返回类型就知道了, 滥用会导致一些性能问题, 毕竟拆装箱多了一步操作。
源码分析 我们先看 valueOf
的源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public final class Long extends Number implements Comparable <Long> { public static Long valueOf (String s) throws NumberFormatException { return Long.valueOf(parseLong(s, 10 )); } public static Long valueOf (long l) { final int offset = 128 ; if (l >= -128 && l <= 127 ) { return LongCache.cache[(int )l + offset]; } return new Long (l); } }
很明显 valueOf
是调用了 parseLong
方法的。 所以这个解析字符串的实现是交由 parseLong
完成的。 然后再从 缓存
中获取, 缓存中没有这个值的话, 再去 new
一个。
再看 parseLong
方法。 在此之前, 先复习下进制转换的算法。 下面的算法公式为 这项算法是秦九韶公式 简单的说, 就是降低了多项式的计算复杂度(叹服古人的智慧, 居然应用到计算机领域)
为了避免溢出, 是基于 负数
进行运算的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public final class Long extends Number implements Comparable <Long> { public static long parseLong (String s, int radix) throws NumberFormatException { long result = 0 ; boolean negative = false ; int i = 0 , len = s.length(); long limit = -Long.MAX_VALUE; long multmin; int digit; char firstChar = s.charAt(0 ); if (firstChar < '0' ) { if (firstChar == '-' ) { negative = true ; limit = Long.MIN_VALUE; } else if (firstChar != '+' ){ throw NumberFormatException.forInputString(s); } if (len == 1 ) { throw NumberFormatException.forInputString(s); } i++; } multmin = limit / radix; while (i < len) { digit = Character.digit(s.charAt(i++),radix); result *= radix; result -= digit; } return negative ? result : -result; } }