代码详解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了一个新的对象,故不等。