equals和==的区别
想起之前面试的一道题,equals和==有什么不同。只记得当时的回答完全糊了。。学习一下。
在说明equals和==的区别前,先简单了解一下JVM中内存分配知识:
JVM中,内存分为:栈内存,堆内存。
二者的区别是: 当我们创建一个对象(new Object)时,就会调用对象的构造函数来开辟空间,将对象数据存储到堆内存中,与此同时在栈内存中生成对应的引用,当我们在后续代码中调用的时候用的都是栈内存中的引用。还需注意的一点,基本数据类型是存储在栈内存中。
简单说,就是:值类型是存储在内存中的堆栈(简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
再来说下java中的数据类型:
1.基本数据类型,也称原始数据类型,八大类:byte,short,int,long,float,double,char,boolean;
ta们之间的比较,应用双等号(==),比较的是ta们的值。
2.复合数据类型(类)
当ta们用(==)进行比较的时候,比较的是ta们在内存中的存放地址,
所以,除非是同一个new出来的对象,ta们的比较后的结果为true,否则比较后结果为false。
了解equals和==的区别:
1.对于==,比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等:即两个变量的值是否相等
如果作用于引用类型的变量,则比较的是所指向的对象的地址:即对于引用型变量表示的是两个变量在栈中存储的地址是否相同,即栈中的内容是否相同
2.对于equals方法:
所有类从Object类中继承equals方法,Object类的的实现代码如下:
boolean equals(Object o)
{
return this==o;
}
也就是说,如果一个类没有对equals方法进行重写(即没有自己定义的equals方法),那么ta将继承Object类的equals方法,equals本身和==没有区别,对于基本数据都是比较值,对于对象都是比较是否为内存地址;
其他类在继承Object类之后对equals方法重写了的话(诸如String、Date等类对equals方法进行了重写:当物理地址不同时,会进一步比较值),则比较的是所指向的对象的内容。
备注:字符串的比较基本上都是使用equals方法。
举例1:
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);
根据上面所讲,第一个是true,第二个是false;
解析:两条new语句创建了两个对象,然后用str1,str2两个变量分别指向两个不同的对象,ta们的首地址是不同的,即str1,str2中存储的数值是不同的,所以表达式str1 == str2将返回false;而两个对象中的内容是相同的,所以str1.equals(str2)返回了true。
举例2:
String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
这次结果:第一个是true,第二个也是true。为什么第二个会是true呢?
这就涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。