转自:https://blog.csdn.net/wxz980927155/article/details/81712342

 

起因

再一次js的json对象的比较中,发现相同内容的json对象使用==比较并不相等。 
例如:

var obj = {};
var obj2 = {};
console.log(obj == obj2); // 结果为false

json在js中代表一个对象==比较的是对象栈中存放引用堆的地址。上面的obj和obj2创建的是两个对象地址肯定不同结果为false。

但最令我不解的是为什么js的字符串比较可以用==来比较字符串的内容是否相等,而java却要使用equals去比较字符串的内容是否相等。但当我发现下面代码的时候又刷新了我这个菜鸟的认知。

String str1 = "test";
String str2 = "test";
System.out.println(str1 == str2); // 结果为true

结果难道不该为false吗?字符串的比较难道不是用equals来比较内容是否相等吗?两个不同的对象创建的内存地址应该是不一样的啊!!后来经过网上查阅资料发现jvm还存在一个字符串常量池。


字符串常量池

让我们先分析一下上述的代码:

在我的理解中常量池应该是为了减少开发者对字符串过度的创建,导致内存使用率的提升,毕竟String类是一个final类,操作字符串永远不会改变当前字符串的值,只会新增一个字符串对象。

String str1 = "test";
/* jvm在编译的时候会先查看str1字面量test是否存放在字符串常量池中有则直
接引用字符串常量池里面的地址,没有则在字符串常量池新创建一个*/
String str2 = "test";
/* str2发现字符串常量池里面已经有了test则直接把字符串常量池里面的地址拿
了过来*/
System.out.println(str1 == str2);
// 最终str1和str2的地址都是相同的结果肯定为true啦

既然都到这里在拓展拓展在走呗

String str1 = new String("test");
String str2 = new String("test");
System.out.println(str1 == str2); // 结果为false
// 这个为什么不为true了呢?

new String()会在代码运行的时候在堆中开辟一个空间存放引用字符串常量池里面的地址但是栈里面引用的堆的地址是不一样的,所以即使引用的字符串常量池里面的地址是一样也永远不可能为true!! 


intern方法

强制String对象使用字符串常量池

String str1 = new String("test");
String str2 = new String("test");
str1 = str1.intern();
str2 = str2.intern();
System.out.println(str1 == str2); // 结果为true

经典面试题

String str1 = new String("test");
// 此代码执行会创建几个对象?
// A:1个或2个,堆中会创建一个,字符串常量池中有test则常量池中不会创建,没有则创建

总结

  1. 字符串字面量会在编译的就开始判断是否在字符串常量池里面创建,而new String()会在代码运行的时候才去判断。

  2. 字符串常量池里面没有此字符串则会创建,有则会去引用字符串常量池里面的字符串。字面量里字符串常量池的地址存放在栈中,new String()则存放在堆中。

java字符串常量池——字符串==比较的一个误区的更多相关文章

  1. Knowledge Point 20180309 字符串常量池与String,intern()

    引言 什么都先不说,先看下面这个引入的例子: public static void test4(){ String str1 = new String("SEU") + new S ...

  2. 8.StringTable(字符串常量池)

    一.String的基本特性 String:字符串,使用一对 "" 引起来表示 String s1 = "atguigu" ; // 字面量的定义方式 Strin ...

  3. 彻底搞清楚class常量池、运行时常量池、字符串常量池

    彻底搞清楚class常量池.运行时常量池.字符串常量池 常量池-静态常量池 也叫 class文件常量池,主要存放编译期生成的各种字面量(Literal)和符号引用(Symbolic Reference ...

  4. java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析

    /** *   栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放  在常量池中). 堆(heap):存 ...

  5. Java字符串常量池

    JVM为了减少字符串对象的重复创建,维护了一个特殊的内存,这段内存被称为字符串常量池. Java中字符串对象的创建有两种形式:一种是字面量形式,String str = "a":一 ...

  6. Java中的字符串常量池

    ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...

  7. Java中String字符串常量池总结

    最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...

  8. java中字符串“不可变性”的破坏,使用反射破坏final属性。以及涉及到字符串常量池的问题。

    大家都清楚java中String类是不可变的,它的定义中包含final关键字.一旦被创建,值就不能被改变(引用是可以改变的). 但这种“不可变性”不是完全可靠的,可以通过反射机制破坏.参考一下代码: ...

  9. Java中String字符串常量池

    首先看一个例子,通过这个例子更能快速理解String常量池 public static void main(String[] args) { String a = "ab"; St ...

随机推荐

  1. [UE4]蓝图调试

    1.蓝图下断点:选择蓝图节点按F9下断点:再按一下F9就会去掉断点. 2.游戏运行到断点会自动这暂停,鼠标移到某个变量上面,会显示该变量的值. 3.按F10执行下一步. 4.蓝图调试没有跳出函数的功能 ...

  2. T-SQL 简单子查询

    1.使用变量的方式实现的查询 use StudentManageDB go declare @StuId int --查询张永利学号 select @StuId=StudentId from Stud ...

  3. spark streaming插入hbase

    import java.sql.{DriverManager, ResultSet} import org.apache.spark._ import org.apache.spark.streami ...

  4. U3D学习003——编辑器使用

    1.skybox 原来的render setting 在2017版本中是lighting标签environment中设置: 或者在摄像机对象中添加skybox组件,进行设置. 2.6张图实现自定义sk ...

  5. 「一本通 6.4 例 4」曹冲养猪(CRT)

    复习一下 扩展中国剩余定理 首先考虑两个同余方程 \[ x \equiv a_1\; mod\; m_1\\ x \equiv a_2\; mod\; m_2 \] 化成另一个形式 \[ x = n_ ...

  6. python中使用tabula爬取pdf数据并导出表格

    Tabula是专门用来提取PDF表格数据的,同时支持PDF导出CSV.Excel格式. 首先安装tabula-py: tabula-py依赖库包括Java.pandas.numpy所以需要保证运行环境 ...

  7. 检查Linux系统cpu--内存---磁盘的脚本

    花了一天写了三条命令分别检查cpu,内存,磁盘 [root@localhost ~]# cat cpu_mem_disk.sh #!/bin/sh # echo "1 检查cpu利用率--- ...

  8. windows下mvn verify异常

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-jarsigner-plugin:1.4:sign (sign) on pr ...

  9. vnc操作指南

    启动 vncserver : vncserver : -geometry 1905x1005 停止: ps aux | grep vnc kill pid 或者 vncserver -

  10. Kettle入门

    kettle  水壶 正如其名“水壶”,将各个地方的水倒进水壶里,再用水壶倒入不同的容器. 勺子-Spoon.bat/spoon.sh 图形界面工具,就是启动上图主界面的命令行. ketchen 厨房 ...