碰到“equals”和“==”这两个字符,老感受差很少;其实仍是有一些区别的,今天就楼主就和你们在确认一遍java
它的做用是判断两个对象的地址是否是相等。即,判断两个对象是否是同一个对象(基本数据类型比较的是值,引用数据类型比较的是内存地址)。web
public class QuoteSame { @Test public void test() { int i = 100;//基本数据类型 int ii = 100;//基本数据类型 Integer j = 100;//引用类型 Integer jj = 100;//引用类型 Integer k = new Integer(100);//引用类型 Integer kk = new Integer(100);//引用类型 System.out.println("i的地址:" + System.identityHashCode(i)); System.out.println("ii的地址:" + System.identityHashCode(ii)); System.out.println("j的地址:" + System.identityHashCode(j)); System.out.println("jj的地址:" + System.identityHashCode(jj)); System.out.println("k的地址:" + System.identityHashCode(k)); System.out.println("kk的地址:" + System.identityHashCode(kk)); //基本类型相互比较其中的值,因此得出true System.out.println("i == ii 结果:" + (i == ii)); //当int的引用类型Integer与基本类型进行比较的时候,包装类会先进行自动拆箱 //而后与基本类型进行值比较,全部得出true System.out.println("i == j 结果:" + (i == j)); //同上,包装类先拆箱成基本类型,而后比较,得出true System.out.println("i == k 结果:" + (i == k)); //都是引用类型,全部比较的是地址,由于j与jj的地址相同,全部true System.out.println("j == jj 结果:" + (j == jj)); //都是引用类型,全部比较的是地址,由于k与kk的地址相同,全部true System.out.println("k == kk 结果:" + (k == kk)); } }
疑问点:为何j和jj的地址是同样的,k与kk的地址却不同呢?
答案:在-128~127的Integer值而且以Integer x = value;的方式赋值的参数,x会从包装类型自动拆箱成基本数据类型,以供重用!因此,j、jj的内存地址都是同样的!
下面咱们把100变成1000试试!ide
public class IntegerSame { @Test public void test() { int i = 10000;//基本数据类型 int ii = 10000;//基本数据类型 Integer j = 10000;//引用类型 Integer jj = 10000;//引用类型 Integer k = new Integer(10000);//引用类型 Integer kk = new Integer(10000);//引用类型 System.out.println("i的地址:" + System.identityHashCode(i)); System.out.println("ii的地址:" + System.identityHashCode(ii)); System.out.println("j的地址:" + System.identityHashCode(j)); System.out.println("jj的地址:" + System.identityHashCode(jj)); System.out.println("k的地址:" + System.identityHashCode(k)); System.out.println("kk的地址:" + System.identityHashCode(kk)); //基本类型相互比较其中的值,因此得出true System.out.println("i == ii 结果:" + (i == ii)); //当int的引用类型Integer与基本类型进行比较的时候,包装类会先进行自动拆箱 //而后与基本类型进行值比较,全部得出true System.out.println("i == j 结果:" + (i == j)); //同上,包装类先拆箱成基本类型,而后比较,得出true System.out.println("i == k 结果:" + (i == k)); //都是引用类型,全部比较的是地址,由于j与jj的地址相同,全部true System.out.println("j == jj 结果:" + (j == jj)); //都是引用类型,全部比较的是地址,由于k与kk的地址相同,全部true System.out.println("k == kk 结果:" + (k == kk)); } }
输出结果:
当j、jj超出-128~127区间的时候,地址就变了,因此比较的结果就是false。
再看其它的包装器自动拆箱状况:svg
类型 | 描述 |
---|---|
Boolean | 所有自动拆箱 |
Byte | 所有自动拆箱 |
Short | -128~127区间自动拆箱 |
Integer | -128~127区间自动拆箱 |
Long | -128~127区间自动拆箱 |
Float | 没有拆箱 |
Doulbe | 没有拆箱 |
Character | 0~127区间自动拆箱 |
它的做用也是判断两个对象是否相等。但它通常有两种使用状况:this
//由于内容相同,返回的都是true System.out.println("j.equals(jj) 结果:" + (j.equals(jj))); System.out.println("(k.equals(kk) 结果:" + (k.equals(kk)));
string是一个很是特殊的数据类型,它能够经过String x = value;的方式进行赋值,也能够经过String x = new String(value)方式进行赋值。spa
String x = value;方式赋予的参数,会放入常量池内存块区域中;
String x = new String(value)方式赋予的参数,会放入堆内存区域中,当成对象处理。
例如:code
public class DemoEquals { public static void main(String[] args) { String a = new String("ab"); // a 为一个引用 String b = new String("ab"); // b为另外一个引用,对象的内容同样 String aa = "ab"; // 放在常量池中 String bb = "ab"; // 从常量池中查找 System.out.println("a地址:" + System.identityHashCode(a)); System.out.println("b地址:" + System.identityHashCode(b)); System.out.println("aa地址:" + System.identityHashCode(aa)); System.out.println("bb地址:" + System.identityHashCode(bb)); //地址相同,因此返回true if (aa == bb) { System.out.println("aa==bb"); } // 地址不一样,非同一个对象,因此返回false if (a == b) { System.out.println("a==b"); } //地址不一样,可是内容相同,因此返回true if (a.equals(b)) { System.out.println("aEQb"); } } }
输出结果
为何string的equals()方法比较返回true,由于string重写了equals()方法,源码以下:xml
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
若是内容相同,则返回true!
总结:若是须要比较某个对象是否相同,必定要重写equals(),比较其中的内容是否相同,若是相同,返回true;不然,返回false!对象