本次将分享一篇在面试过程中很多人走过的坑,当然是也是我这个只是更加熟悉的一个过程,大佬都懂,主要分享给像我这样的小白,废话不多说,直接上题目:
public void test() {
Integer i=new Integer(1);
Integer j=new Integer(1);
System.out.println(i==j);//false
Integer m=1;
Integer n=1;
System.out.println(m==n);//true
Integer x=128;
Integer y=128;
System.out.println(x==y);//false
}
其实这类题就是考我们对基本数据类型和内存等知识考察,下面看详细过程吧!
二、先从数据类型说起
1.java数据类型前世今生
首先,我们知道java有两种数据类型,分别是基本数据类型和引用数据类型
(1)基本数据类型:boolean、byte、int、char、long、short、double、float;
(2)引用数据类型:类,数组,接口;
参考文献
https://blog.csdn.net/baidu_31657889/article/details/51939332
关于整数型的转换总结
https://blog.csdn.net/yyp0304Devin/article/details/105328471
这时有人可能会问,不是说题吗?为什么会说到数据类型。
为什么会说数据类型,就是因为我们有时候不知道数据类型的转换或者数据类型之间的关系。
在本题中,我们看似Integer的参数为1,但是他们为什么输入的结果为false;
顺便可以看看“==”有关知识。
https://blog.csdn.net/yyp0304Devin/article/details/105659819
三、引出包装类(Wrapper)
看完这个图就清楚多了,int是java的基本数据类型,而Integer是int的包装类,学过java的人都知道,在java中有个类,这个类是Object,所有的类都有间接或直接的继承这个类,这里的Integer包装类也一样,会继承Object。基本Integer是一个类,所以他在实例化的时候会创建成一个对象,Integer变量其实就是一个Integer对象的引用,看看他的内存结构。
四、详解
Integer i=new Integer(1);
Integer j=new Integer(1);
System.out.println(i==j);//false
内存结构
画的比较low,勿喷。
他们所指的内存不是一个,所以执行结果会为false。
Integer i = 1;
Integer j = 1;
System.out.print(i == j); //true
Integer x=128;
Integer y=128;
System.out.println(x==y);//false
这来两个看起来相似,但是为什么一个执行结果为ture,一个结果为false。
原因:
java在编译Integer i = 100 ;时,会翻译成为Integer i = Integer.valueOf(100)。而java API中对Integer类型的valueOf的定义如下,对于-128到127之间的数,会进行缓存,Integer i = 127时,会将127这个Integer对象进行缓存,下次再写Integer j = 127时,就会直接从缓存中取,就不会new了。
Integer内容定义了IntegerCache结构,IntegerCache中定义了Integer[],
保存了从-128~127范围的整数,如果我们使用自动装箱的方式,给Integer赋值的范围在
-128-127范围之内,可以直接使用数组中的元素,不用再去new了,目的:提高效率。
五、源码分析
(1)在-128~127之内:静态常量池中cache数组是static final类型,cache数组对象会被存储于静态常量池中。
cache数组里面的元素却不是static final类型,而是cache[k] = new Integer(j++),
那么这些元素是存储于堆中,只是cache数组对象存储的是指向了堆中的Integer对象(引用地址)
(2)在-128~127 之外:新建一个 Integer对象,并返回。
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high) {
return IntegerCache.cache[i + (-IntegerCache.low)];
}
return new Integer(i);
}
IntegerCache是Integer的内部类,源码如下:
缓存支持自动装箱的对象标识语义 -128和127(含)。
缓存在第一次使用时初始化。 缓存的大小可以由-XX:AutoBoxCacheMax = 选项控制。
在VM初始化期间,java.lang.Integer.IntegerCache.high属性可以设置并保存在私有系统属性中
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;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
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);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++) {
cache[k] = new Integer(j++); // 创建一个对象
}
}
private IntegerCache() {}
}
有不对的地方,还请大佬不吝赐教!
作者:似水流年,是谁苍白了等待