快捷搜索:  汽车  科技

java代码常见问题汇总(来看看Java中那些让人疑惑的代码操作)

java代码常见问题汇总(来看看Java中那些让人疑惑的代码操作)private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; // 检查虚拟机里面有没有相应的配置,如果有,就取该值,没有就取127 String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(

java代码常见问题汇总(来看看Java中那些让人疑惑的代码操作)(1)

码出未来,码到成功

今天1024程序员节,祝广大程序员当然也包括我自己,头发越来越好,bug越来越少,需求变更没有(估计不可能)。

我们今天就不写概述了,直接一点,直接上代码,非常简单的一段代码,如下:

public static void main( String[] args ) { Integer a = 100; Integer b = 100; System.out.println(a == b); Integer c = 1000; Integer d = 1000; System.out.println(c == d); }

执行一下:

true false

咦,为啥是这个结果呢,不应该两个结果一样吗?要么都是true,要么都是false,怎么会不一样呢?我相信肯定很多人都不会思考,直接打开百度搜答案,这种习惯不是很好,至少你得思考下再百度吧。

我们写的Java文件是要编译之后才能执行的,是不是编译的时候编译器做了什么动作呢?我们找到编译后的.class文件,内容如下:

public static void main(String[] args) { Integer a = Integer.valueOf(100); Integer b = Integer.valueOf(100); System.out.println((a == b)); Integer c = Integer.valueOf(1000); Integer d = Integer.valueOf(1000); System.out.println((c == d)); }

是不是跟我们写的不一样,编译之后加上了valueOf,那我们就来看一下Integer的valueOf方法,代码如下:

/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required this method should generally be used in preference to * the constructor {@link #Integer(int)} as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127 * inclusive and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i (-IntegerCache.low)]; return new Integer(i); }

我们结合上面的注释,其实已经可以明白了,Integer的作者在写这个类时,为了避免重复创建对象,对Integer值做了缓存,如果这个值在缓存范围内,直接返回缓存好的对象,否则new一个新的对象返回,具体缓存了哪些内容呢?我们看一下IntegerCache这个类:

private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; // 检查虚拟机里面有没有相应的配置,如果有,就取该值,没有就取127 String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int ignore it. } } high = h; // 创建缓存数组,并给数组赋值 cache = new Integer[(high - low) 1]; int j = low; for(int k = 0; k < cache.length; k ) cache[k] = new Integer(j ); // range [-128 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }

这是一个内部静态类,该类只能在Integer这个类的内部访问,这个类在初始化的时候,会去加载JVM的配置,如果有值,就用配置的值初始化缓存数组,否则就缓存-128到127之间的值。

所以再看我们之前的代码,现在就清楚了,100取得是缓存里面的对象,==又是比较的地址,所以对100而言,地址都是一样的,而1000是新new的,所以肯定不一样。如果要比较值得话,要用equals。在Java中没有重载操作符这一说,特别是从其它语言转到Java的童鞋们要注意。

猜您喜欢: