一直以来老为这个问题头疼,最近亲自翻阅了各种书籍,又亲身实验。得出如下结论,如有纰漏之处,烦请各位不吝指正!
先上结论:
1、equals方法比较两个对象的内容(不能用于基本数据类型)
2、==比较两个对象是否是同一对象,或者说对象在内存中的首地址是否相同(仅在引用类型中做此功能)
java数据类型可分为两类:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址。
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址(等同于==)。但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
至于其他复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
1)两个都是new出来的String类对象
public class Test { public static void main(String [] args) { String a=new String("abc"); String b=new String("abc"); System.out.println(a==b); System.out.println(a.equals(b)); } }
结果输出为
false
true
new的话就不可能进入sting pool了,先在栈区创建一个a指针,在堆区创建一块新的内存区指向它。
由此可知,String类里==比较的是存储地址(a和b不等)。而在String类中重写的equals方法比较的只有内容。
所以前者为false,后者为true
2)没有new的String类对象
public class Test { public static void main(String [] args) { String a="abc"; String b="abc"; System.out.println(a==b); System.out.println(a.equals(b)); } }
结果输出为
true
true
这里 "== "判断的是a,b 是否都指向"abc"这个字符内存池,在堆区里面的一块相同地址!s1 与 s2 引用同一个 String 对象“abc”
3)一个有new,一个没new的String对象
public class Test { public static void main(String [] args) { String a = "abc"; String b = new String("abc"); System.out.println(a==b); System.out.println(a.equals(b)); } }
输出结果为:
false
true
a 指向"abc"这个字符内存池,等于创建了一个地址a(栈)--->abc(堆)
b是new出来的对象,先在栈区创建一个b指针,在堆区创建一块新的内存区指向它,等于创建了两个地址。(栈)abc--->b(堆)
==比较的是地址,a和b地址不同。所以为false
而在String类中的equals方法比较内容,所以为true
总结来说:
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
附:堆与栈的区别
1、栈区(stack)― 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) ― 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
参考文章:http://www.cnblogs.com/FlyFive/archive/2013/01/05/2845314.html
http://www.cnblogs.com/dolphin0520/p/3592500.html
http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html