浅析java中String类型中“==”与“equal”的区别

 更新时间:2020年08月21日 10:15:15   作者:计通罗主任  
这篇文章主要介绍了浅析java中String类型中“==”与“equal”的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、前言

1.1、首先很多人都知道,String中用“==”比较的是地址,用equals比较的是内容,很多人对此用的是记忆法,通过记忆来加强此的引用,但是其真正的原理其实并不难,当我们真正明白其为什么的时候,用起来也会更加灵活,更加有底气(形容得不太好,朋友别见怪);

二相关知识的准备

  • 类型常量池
  • 运行时常量池
  • 字符串常量池

我们今天讨论的主题是当然是字符串常量池:
为什么在这要把另外两个常量池拿出说一下呢,首先小生我在网上或者cnds上看到很多人在争论字符串常量池是存在与方法区还是堆里面,因此我在这里面非常负责任的告诉各位读者:
1、类型常量池,存放在方法区里面,每个class文件都有一个
2、运行时常量池、存放在方法区里面,所有class共用
3、字符串常量池:存放在堆区里面
而且字符串常量池有一个特点:存放的常量唯一:三、 开始

3.1,情况一

public class Test2 {
	public static void main(String[] args) {
		
		String a ="张敬轩";
		String b ="张敬轩";
		
		System.out.println(a == b);
		System.out.println(a.equals(b));
		
	}
}

运行结果:

在这里插入图片描述

  • true
  • true

解释:因为当我们String a = “张敬轩”;的时候,会在堆里面的字符串常量池里面“搜索”是否有“张敬轩”这个对象,

  • 有:就会将“张敬轩这个对象的地址指向a”
  • 没有:就会在字符串常量池里面新建立一个“张敬轩”,然后就会把地址引用赋值给a

当再声明String b = “张敬轩";和第一次声明String = “张敬轩”;一样,先”搜索“,然后因为已经存在了”张敬轩“这个对象,那么就不会再创建对象,而是将存在的”张敬轩“的地址引用赋值给b,所以
a和b的地址一样,内容自然也一样,所以两个结果为true,不懂各位朋友懂没懂?

3.2,情况二;

public class Test2 {
	public static void main(String[] args) {
		
		String a ="张敬轩";
		 
		String b = new String("张敬轩");
		
		System.out.println(a == b);
		System.out.println(a.equals(b));
		
	}
}

结果是

在这里插入图片描述

false,true
解释
String a = “张敬轩”;
已经解释过了,是在堆里面的字符串常量池创建对象
String b = new String(“张敬轩”);
这个也是在堆区里面创建对象,但是不是在字符串常量池里面创建对象
两个不同的对象,地址自然不同,类容都是张敬轩,所以结果是false,true

3.3、情况三

public class Test2 {
	public static void main(String[] args) {
		
		String a = new String("张敬轩");
		 
		String b = new String("张敬轩");
		
		System.out.println(a == b);
		System.out.println(a.equals(b));
		
	}

}

结果:false,true

在这里插入图片描述

解释,因为new (“张敬轩”);表示在堆区的非字符串常量池里面创建了两个不同的对象,两次new就创建了两个,所以地址是不同的,因此结果是false,true

3.4、情况四

public class Test2 {
	public static void main(String[] args) {
		
		String a = "张"+"敬轩";
		String b = "张敬轩";
		System.out.println(a == b);
		System.out.println(a.equals(b));
		
	}
}

结果是:true,true

在这里插入图片描述

解释:String = “张敬” + ”轩“;
在编译的时候就已经开始进行计算:这是Java编译的优化机制,所以a指向的地址依旧是”张敬轩“;所以情况和前面的情况一一致,所以是true,true
(注意Java编译优化机制只针对常量不针对变量 a = a+ b(这个是没有优化机制的,关于Java编译机制,各位小伙伴可以去百度了解一下))

3.5、情况五

public class Test2 {
	public static void main(String[] args) {
		
		String a = "张";
		String b = "敬轩";
		String c =a+b;
		String d = "张敬轩";
		System.out.println(d == c);
		System.out.println(d.equals(c));
		
	}
}

结果:

在这里插入图片描述

解释:因为a 和 b是变量,不存在什么Java优化机制,而是将两个c = a + b存放在的是堆区的非字符常量池里面,所以是两个不同的对象,自然为false,true
3.6、最后一种情况

public class Test2 {
	public static void main(String[] args) {
		
		String a = "张";
		String b = "敬轩";
		String c =(a+b).intern();
		String d = "张敬轩";
		System.out.println(d == c);
		System.out.println(d.equals(c));
		
	}

}

结果:

在这里插入图片描述

解释:intern();方法是将堆区里面的非字符常量池里面的对象强行放到字符常量池里面,因为字符常量池里面对象的唯一性,如果字符串常量池里面已经有了和”张敬轩“一样的对象,就会将其地址引用赋值给c,没有就相当于创建一个(也就是和之前堆区里面那个对象一样的对象),有了的话,就会将原来有的那个“张敬轩”对象赋值给c,因为地址一样,所以为true

总结:

== 比较的地址 (如果对象存在字符串常量池,而且类容相同,那么 == 返回的是true )
equal 比较的是内容 (内容相同返回便是true)(所以在以后的开发中一般是用equal比较字符串的

各位朋友如果有错的及时评论区指出,谢谢大家的支持

到此这篇关于浅析java中String类型中“==”与“equal”的区别的文章就介绍到这了,更多相关java String类型 ==与equal内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Tomcat调优详解

    Tomcat调优详解

    这篇文章主要介绍了Tomcat调优方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Java中的包(package)是什么和使用方法

    Java中的包(package)是什么和使用方法

    包是Java中一种强大的组织代码的工具,它们帮助开发者将代码分组,防止命名冲突,并通过控制访问级别来增强代码的安全性,这篇文章主要介绍了Java中的包(package)是什么和如何使用它们,需要的朋友可以参考下
    2024-07-07
  • 优化Java内存管理来防止“GC”错误的方法详解

    优化Java内存管理来防止“GC”错误的方法详解

    垃圾回收(GC)是 Java 中的一个重要机制,它可以管理内存并回收不再使用的对象所占用的资源,在本文中,我们将探讨一些技巧,帮助您避免这一错误,确保您的 Java 应用程序顺利运行,需要的朋友可以参考下
    2023-11-11
  • springcloud使用feign调用服务时参数内容过大问题

    springcloud使用feign调用服务时参数内容过大问题

    这篇文章主要介绍了springcloud使用feign调用服务时参数内容过大问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 一文搞懂java反射基本API

    一文搞懂java反射基本API

    这篇文章主要为大家介绍了一文搞懂java反射基本API,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java中转义字符反斜杠\的代替方法及repalceAll内涵解析

    Java中转义字符反斜杠\的代替方法及repalceAll内涵解析

    这篇文章主要介绍了Java中转义字符反斜杠\的代替方法及repalceAll内涵解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 深入探究Java线程与进程有哪些区别

    深入探究Java线程与进程有哪些区别

    这篇文章主要介绍了Java并发编程之线程创建,进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是一个实体,一个进程中至少有一个线程,下文更多相关内容需要的小伙伴可以参考一下
    2022-04-04
  • Java代码的三根顶梁柱:循环结构

    Java代码的三根顶梁柱:循环结构

    这篇文章主要介绍了JAVA 循环结构的相关资料,文中讲解的非常细致,示例代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2021-08-08
  • 解决微服务中关于用户token处理到的坑

    解决微服务中关于用户token处理到的坑

    这篇文章主要介绍了解决微服务中关于用户token处理到的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java项目中如何引入Hutool工具类并正确使用它

    Java项目中如何引入Hutool工具类并正确使用它

    Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,这篇文章主要给大家介绍了关于Java项目中如何引入Hutool工具类并正确使用它的相关资料,需要的朋友可以参考下
    2024-01-01

最新评论