今天研究了Interger的源代码。 看了源代码之后知道了根本。 以前做过的关于Interger的问题都解决了。
今天以面试问题为例
Integer a5=128;
Integer a6=128;
Integer a7=127;
Integer a8=127;
integera9=newinteger(127;
system.out.println(A5==A6 ); //false
system.out.println(A7==A8 ); //true
system.out.println(A9==A8 ); //false
system.out.println(A9.equals ) A8 ); 在程序运行jdk1.7的环境中为false。 对==匹配的地址的引用是众所周知的。 (不知道的话可以自己搜索一下。 网上有很多例子。 )
综上所述,可以得出a8和a9的数值相等,但参照的地址不同。 为什么呢?
首先,虚拟机在编译过程中优化代码。 也就是说,上面的代码可能不是我们想要的。 首先来看看编译后代码的情况。
(class文件反编译后的代码)
integera5=integer.valueof(128;
integera6=integer.valueof(128;
integera7=integer.valueof(127;
integera8=integer.valueof(127;
integera9=newinteger(127;
system.out.println(A5==A6 );
system.out.println(A7==A8 );
system.out.println(A9==A8 );
system.out.println(A9.equals ) A8 );
编译器优化后实际执行的代码是这样的。=128针对integer.valueof(128 )进行了优化。
但是Integer.valueOf做了什么呢? 为什么比较两个128会成为不同的对象呢? 比较两个127的话会变成相同的数据吗?
带着疑问打开了jdk的源代码(大家可以直接在intellij idea上看到源代码) )。
publicstaticintegervalueof{
assert IntegerCache.high=127;
if (I=integer cache.lowi=integer cache.high ) )。
returnintegercache.cache [ I (-integer cache.low );
returnnewinteger(I;
}
首先,一眼看过去,这是一种静态方法,可以直接从Interger对象调用。 看了里面的东西,第一次看的时候就猜到了作者的意思。 判断发送来I的数据是否在IntegerCache.low和IntegerCache.high的中间,如果有,则不返回integer cache.cache [ I (-integer cache.ligh ) ] 接下来,按照芋头的顺序,看看上面的三样东西是什么。
privatestaticclassintegercache {
静态final int low=-128;
静态文件输入高;
static final Integer cache[];
静态{
//highvaluemaybeconfiguredbyproperty
int h=127;
stringintegercachehighpropvalue=
sun.misc.VM.getsavedproperty (Java.lang.integer.integer cache.high );
集成缓存高性能!=null ) {
inti=parseint (集成电路);
I=math.max(I,127 );
//maximumarraysizeisinteger.max _ value
h=math.min(I,integer.max_value-(-low )-1 );
}
high=h;
cache=newinteger[(high-low )1];
int j=low;
for(intk=0; k cache.length; k )
che[k]=newinteger(j );
}
私有积分缓存
}
研究代码时,我们发现IntegerCache是一种静态、私有的方法,其中包含许多静态对象。 什么是静态? 像这样简单地被认为是全局变量,谁都可以使用的,被缓存的数据。 low为-128 high,默认值也可以配置为127。 上述含义是,程序启动时初始化的部分数据存在于内存中。 这些数据是什么呢?
for(intk=0; k cache.length; k )
che[k]=newinteger(j );
}
您可以看到这里正在进行for循环。 那里有new关键字,每次都会创建对象。 内容是low和high中间的所有数据面,也就是从(128 )到(127 )的数据,共计255 Interger对象。 创建这些对象后,应该存在对他们地址的引用,这是数据,静态存在于缓存中,不是可变的。
知道了这些数据之后,让我们来看看上面代码的含义。
integer.valueof(I )确定传入的I是否在-128和127之间,如果是,则返回returnintegercache.cache [ I (-integer cache.low ) ]; 如果没有,则返回new对象。
所以呢
integer.valueof(128 )时大于127,每次都是new的新对象。
integer.valueof(127 )为127,因此不再需要从高速缓存中检索127个地址并创建新的对象。
所以呢
system.out.println(A5==A6 ); //false
system.out.println(A7==A8 ); //true
每次new的都是新的对象,无论是否存在于缓存中,所以请输入system.out.println(a9==a8 ); //false
这是我看了interger的源代码后的感受。 如果有不到的地方或者错误的地方,请大家一起进步。
}