JAVA中equals和==的区别

==比较的是堆内存中的地址是否相同

     String s1 ="aaa";
     String s2 ="aaa;
     System.out.println(s1==s2);//true

s1和s2是对象的引用存放在栈中,首先s1创建在栈中,在堆中会寻找是否有aaa的,如果没有就把aaa放入常量池中,其次s2对象引用也存放在栈中,也去常量池中寻找是否有aaa,如果有直接指向,所以s1和s2指向的是一个常量池的内存地址,而==比较就是堆的内存地址,所以结果为ture

equals本质上比较引用对象的地址本质上就是==
比较的是内存堆中的地址
在这里插入图片描述
String重写的equals方法,我们来看下String类的equals方法:
在这里插入图片描述
首先判断是否是String类型
获取原本String类型的长度
如果原本String类型长度等于比较String的类型长度
分别用2个字符数组存放
用while以此重第一个字符开始比较如果不等返回false
比较完没有发现不同,返回true

总结:如果类没有重写equals方法,那么equals等于==
如果重写了,equals将依次比较每个字符的值

来一组==来判断下String类型

    String s1 = new String("zs");
	String s2 = new String("zs");
	//==比较的是引用的堆的对象是否相等 图中2个对象创建了2个不一样的堆 false
	System.out.println(s1 == s2); //false
	String s3 = "zs";``
	String s4 = "zs";
	//==比较的是引用堆的对象是否相同 
	System.out.println(s3 == s4);  //true
	
	System.out.println(s3 == s1); //false
	
	String s5 = "zszs";
	//字符串是一个不可变的对象,当我们创建新的对象的时候 会使用新的方法new进行创建
	//s3 s4是字符串变量,其指向的对象可以改变,程序在编译期就不能完全确定其值,
	//故变量参与拼接形成的字符串放入堆中
	String s6 = s3+s4;
	System.out.println(s5 == s6);//内容一样  引用的堆是不一样的 一个引用的是常量池,一个引用的是堆   所以是false
	final String s7 = "zs";
	final String s8 = "zs";
	//final修饰的对象是常量,因为都是常量在编译前就确定,由编译器优化
	//在编译期就将+两边合并了,直接合并成一个常量"zszs"故引用一个,常量池的内容是可以共享的
	String s9 = s7 + s8;
	System.out.println(s5 == s9);//true
	
	//s3 s4是字符串变量,其指向的对象可以改变,程序在编译期就不能完全确定其值,故变量参与拼接形成的字符串放入堆中
	//s5指向的是常量池的引用
	final String s10 = s3+s4;
	System.out.println(s5 == s10);//false
	****

在这里插入图片描述
字符串常量相加,不会用到StringBuilder对象,有一点要注意的是:字符串常量和字符串是不同的概念,字符串常量储存于方法区,而字符串储存于堆(heap)。

对于字符串:其对象的医用都是存储在栈中,如果是编译期就创建好(直接用双引号定义的)就存储在常量池中,如果是运行期间(new出来的)才能确定就存储在堆中。对于eques相等的字符串,常量池用于只有一份,在堆中有多份

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值