一、equals和==的区别
1.1、equals之string字符串的比较
1.1.1、源码如下图
if (this == anObject) {
return true;
}
当两者是同一地址的时候,则直接返回true,即相等,若两者有一者不是string类型,则跳过两个if,返回false;
由源码可知,字符串先比较的是两者的大小,若不等,则直接返回false;当长度相等时,进而将字符串转为char数组来对每一个字符进行比较,由此可见,equals比较的是字符串的值是否想等。
1.2、equals之对象的比较
说明:若该对象没有重写Object的equals,则默认引用object的equals方法,源码如下
当是对象(没有重写equals)进行比较,则此时比较的是两者的地址是否相等
package com.qm.test.equals;
import org.junit.Test;
public class EqualsDemo {
@Test
public void test1(){
EqualsDemo e1 = new EqualsDemo();
EqualsDemo e2 = new EqualsDemo();
EqualsDemo e3 = e1;
System.out.println(e1.equals(e2));//等同e1==e2,false
System.out.println(e1.equals(e3));//等同e1==e3,true
System.out.println(e2.equals(e3));//等同e2==e3,false
}
}
测试结果分析:
1、因为e1和e2都是直接new对象,即在堆内存中开辟空间,两者地址肯定不一样,当两者进行equals比较时,返回false。
2、因为e1直接把它的栈引用,赋给了e3(即,e3也指向e1在开辟的空间),两者比较时返回true。
3、e2与e3相比较同1.
注意:若互相比较的对象,重写了equals方法,则按照重写的进行比较
2.1、==的比较
2.1.1、基本数据类型·
当要比较的对象时基本数据类型(java中数据类型,大致分为两类,一,基本数据类型(八个),二、引用数据类型类型(也可称复合数据类型)),则此时返回的结果是与equals一样,比较的是值是否相等,而不是地址,
2.1.2、引用数据类型
当引用数据类型是基本数据类型的包装类型时,两者进行==比较,也是比较的是值是否相等。 可自行查看源码。
当是其他的数据类型时,则比较的是两者在堆内存中的地址是否相等(即是否指向同一个堆内存)。
二、String类的说明
2.1、String类的创建
String a1 = new String(“a1”);当程序运行后则会发生这几件事,先在string常量池中查询有没有a1字符串,若没有则创建a1字符串,且将其放入常量池中,若有,则不创建,然后,由于使用了new关键字,则会在堆内存中开辟空间,然后在栈内存中有该堆内存的引用(可以理解为堆内存的地址,被栈内存的a1掌握),同时该值为a1,
String a2 = “aaa”;,先去查看常量池中有没有aaa字符串,若有,则直接将该引用地址赋给a2,若没有,则创建且放入常量池,再将引用地址赋给a2,
若考虑性能问题,建议使用后者创建字符串。
2.2、string类的值的比较
public class EqualsDemo
{
public static void main(String[] args)
{
String s1 = new String(“xx”);
String s2 = new String(“xx”);
String s3 = “xx”;
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
}
}
说明:
1、s1==s2,比较的是堆内存地址是否相等,由于两者都单独在堆内存中开辟了空间,所以返回false,s1.equals(s2),比较的是值,即返回true。
2、s1.equals(s3),由于创建s1时,xx字符串已经在常量池中,存在,所以直接把该引用赋给s3,两者值相等。
3、若s3发生改变,如s3=s3+”bb”;则先会在常量池中查找xxbb,没有则创建,同时将该引用赋给s3,但注意的是xx字符串,并没有在string常量池中消失。
个人总结
由于这是本人第一篇博文,语言表达、文字排版上难免有点欠缺,请大家多多谅解,若有错误的地方,恳请,诸位指正。谢谢!
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/12351.html