代码详解java里的“==”和“equels”区别
测试1:
先看一组String类型比较,废话不多说,直接上代码:
publicclassTest{
publicstaticvoidmain(String[]args){
Stringa="java书苑";
Stringb="java书苑";
Stringc=newString("java书苑");
Stringd=newString("java书苑").intern();
if(a==b){
System.out.println("a==b");
}else{
System.out.println("a!=b");
}
if(a.equals(b)){
System.out.println("a.equals(b)");
}else{
System.out.println("!a.equals(b)");
}
if(a==c){
System.out.println("a==c");
}else{
System.out.println("a!=c");
}
if(a.equals(c)){
System.out.println("a.equals(c)");
}else{
System.out.println("!a.equals(c)");
}
if(a==d){
System.out.println("a==d");
}else{
System.out.println("a!=d");
}
if(a.equals(d)){
System.out.println("a.equals(d)");
}else{
System.out.println("a.equals(d)");
}
}
}
输出结果:
a==b a.equals(b) a!=c a.equals(c) a==d a.equals(d)
总结:
结果a==b:程序在运行的时候会创建一个字符串缓冲池,在Stringa=“java书苑”时,“java书苑”被放到了字符串缓冲池中,当Stringb=“java书苑”创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,所以在b被创建的时候,程序找到了具有相同值的a,将b引用a所引用的对象。所以a和b引用的同一个对象,故a==b。
结果a!=c:Stringc=newString(“java书苑”)时new了一个新的对象,故不从String缓冲池寻找,二十直接创建一个新的对象。所以a!=c。
结果a==d:当调用intern方法时,如果池已经包含一个等于此String对象的字符串(该对象由equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并且返回此String对象的引用。所有d调用的同样是a的对象。
equals比较的是值,故值一样时便相等。
测试2:
这是一组int类型和Integer类型的测试:
publicclassTest{
publicstaticvoidmain(String[]args){
inta=127;
inta1=127;
intb=128;
intb1=128;
Integerc=127;
Integerc1=127;
Integerd=128;
Integerd1=128;
if(a==a1){
System.out.println("a==a1");
}else{
System.out.println("a!=a1");
}
if(b==b1){
System.out.println("b==b1");
}else{
System.out.println("b!=b1");
}
if(c==c1){
System.out.println("c==c1");
}else{
System.out.println("c!=c1");
}
if(d==d1){
System.out.println("d==d1");
}else{
System.out.println("d!=d1");
}
}
}
输出的结果:
a==a1 b==b1 c==c1 d!=d1
结果”a==a1”和”b==b1”:int是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象,多以比较的时候”a==a1”和”b==b1”。
结果“c==c1”和“d!=d1”这里可能有人会有疑问,为什么“d!=d1”.我们一起看一下Integer的源码。
/** *Cachetosupporttheobjectidentitysemanticsofautoboxingforvaluesbetween *-128and127(inclusive)asrequiredbyJLS. * *Thecacheisinitializedonfirstusage.Thesizeofthecache *maybecontrolledbythe-XX:AutoBoxCacheMax=option. *DuringVMinitialization,java.lang.Integer.IntegerCache.highproperty *maybesetandsavedintheprivatesystempropertiesinthe *sun.misc.VMclass. */ privatestaticclassIntegerCache{ staticfinalintlow=-128; staticfinalinthigh; staticfinalIntegercache[]; static{ //highvaluemaybeconfiguredbyproperty inth=127; StringintegerCacheHighPropValue= sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if(integerCacheHighPropValue!=null){ inti=parseInt(integerCacheHighPropValue); i=Math.max(i,127); //MaximumarraysizeisInteger.MAX_VALUE h=Math.min(i,Integer.MAX_VALUE-(-low)-1); } high=h; cache=newInteger[(high-low)+1]; intj=low; for(intk=0;k =127; if(i>=IntegerCache.low&&i<=IntegerCache.high) returnIntegerCache.cache[i+(-IntegerCache.low)]; returnnewInteger(i); }
结论:这里Integer会初始化一个[-128,127]的常量池,如果数值在这个范围时,则引用的是同一个对象,如果不在这个范围,通过源码可以看出返回的是new了一个新的对象:returnnewInteger(i);
所以,结果“c==c1”是引用了同一个对象,结果“d!=d1”,是new了一个新的对象,故不等。