微商各种软件拿码渠道,网站优化建设公司,网站总体规划,中国建网站报价Integer经典面试问题#xff1a;两个Integer对象都赋值为128#xff0c;这两个对象比较是否相同#xff1f;为什么#xff1f; 
回答这个问题#xff0c;首先我们要知道#xff0c;在Java中#xff0c;当你写Integer a  1; 实际上是调用了Java的自动装箱功能。这会将整数…Integer经典面试问题两个Integer对象都赋值为128这两个对象比较是否相同为什么 
回答这个问题首先我们要知道在Java中当你写Integer a  1; 实际上是调用了Java的自动装箱功能。这会将整数 1 自动装箱为Integer对象然后将这个对象赋值给变量a。 
自动装箱功能是由编译器自动插入的实际上它相当于执行了如下的代码 
Integer a  Integer.valueOf(1);这里的valueOf方法是Integer类的一个静态方法它的作用就是将传入的参数通常是基本数据类型自动转换为对应的包装类对象。对于Integer类来说就是将整数值转换为Integer对象。 知道这一点之后我们看看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(int)因为通过缓存频繁请求的值该方法可能会产生更好的空间和时间性能。此方法将始终缓存-128到127(包括-128到127)范围内的值并可能缓存此范围之外的其他值。 接下来看看IntegerCache缓存的实现 
/*** Cache to support the object identity semantics of autoboxing for values between* -128 and 127 (inclusive) as required by JLS.** The cache is initialized on first usage.  The size of the cache* may be controlled by the {code -XX:AutoBoxCacheMaxsize} option.* During VM initialization, java.lang.Integer.IntegerCache.high property* may be set and saved in the private system properties in the* sun.misc.VM class.*/private static class IntegerCache {static final int low  -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h  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_VALUEh  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() {}
}缓存在第一次使用时初始化。缓存的大小可以通过-XX:AutoBoxCacheMax选项来控制。在虚拟机初始化过程中可以设置java.lang.Integer.IntegerCache.high属性并保存在sun.misc.VM类的私有系统属性中。 IntegerCache缓存范围的最小值固定为-128最大值默认为127.但是最大值是可以被重新定义的那么可定义的范围是多少呢 
i  Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h  Math.min(i, Integer.MAX_VALUE - (-low) -1);上面的两行已经定义了IntegerCache缓存最大值的范围 定义最大值范围大于等于127  定义最大值范围小于等于Integer.MAX_VALUE - (-low) -1;  
Integer.MAX_VALUE的定义2的23次方 - 1 
Native public static final int   MAX_VALUE  0x7fffffff;IntegerCache缓存的范围定义好后为区间范围赋值。 
for(int k  0; k  cache.length; k)cache[k]  new Integer(j);最后通过断言检查 IntegerCache.high 是否大于等于 127。 
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high  127;IntegerCache.high 是 Java 中 Integer 缓存的一部分这个缓存用于存储 -128 到 127 之间的整数以提高这个范围内的整数在多次使用时的性能。 
assert 是一个用于调试的语句当 IntegerCache.high  127 时该语句将抛出 AssertionError。 
JLS7 5.1.7 是 Java Language Specification 的一个部分这部分规定了对于字符串字面值编译器必须将它们在编译期放入字符串池中以避免内存浪费。 
这段代码的目的是确保 IntegerCache 的范围在 [-128, 127] 内因为这是 String 缓存这个优化策略可以应用的范围。如果 IntegerCache 的范围超出了这个范围那么可能会导致无法进行这种优化从而可能降低性能。 
需要注意的是assert 语句在默认情况下是关闭的如果你想要开启它需要在启动 JVM 时添加 -ea或 -enableassertions参数。 
因此当写 Integer i1  128; 和 Integer i2  128; 实际上在内存中创建了两个不同的对象即使它们包含相同的值。 
可以通过调用 equals() 方法来比较这两个对象的内容是否相同而不是使用  运算符。这是因为 在比较对象时实际上是检查它们是否指向内存中的同一个对象而不是比较它们的内容。而 equals() 方法则是比较对象的内容。 
如果使用 equals() 方法来比较这两个对象它们会被视为相等因为它们包含相同的内容。但是如果你使用 运算符来比较它们会被视为不相等因为它们是不同的对象。