转自: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. 大数据:Parquet文件存储格式【转】

    一.Parquet的组成 Parquet仅仅是一种存储格式,它是语言.平台无关的,并且不需要和任何一种数据处理框架绑定,目前能够和Parquet适配的组件包括下面这些,可以看出基本上通常使用的查询引擎 ...

  2. C语言强化——链表(1)

    目录 链表的增删(不带头结点) 链表相关面试题 合并两个有序链表 单链表原地逆置 找出链表的倒数第四个节点 找出链表的中间节点 判断单链表是否有环 求链表交点 删除有序单链表中重复的元素 链表按奇数. ...

  3. mysql查询中取差集的问题

    有个场景 现在有个打卡的记录表(daka),记录了用户每天的打卡信息,同时还有个运动打卡表(sport_daka),如果用户有运动打卡则在运动打卡表里面记录. 现在要统计用户的每天的打开信息,包括运动 ...

  4. [UE4]用.csv作为配置文件

    csv文件,以逗号分割的值的文件. csv文件的第一行一般为表头,第二行开始是字段值. .csv文件,纯文本,可以用记事本打开看到内容. excel支持csv文件,方便修改. 导入csv文件: 一.建 ...

  5. [UE4]C++实现动态加载的问题:LoadClass<T>()和LoadObject<T>() 及 静态加载问题:ConstructorHelpers::FClassFinder()和FObjectFinder()

    转自:http://aigo.iteye.com/blog/2281558 动态加载UObject和动态加载UClass分别用LoadObject<T>(),和LoadClass<T ...

  6. root用户以修改文件的方式,修改用户密码

    老早就听说linux的用户密码只是存储在普通的文本文件里,但一直没去了解,今天遇上了需要强行修改的情况... 给碰到个奇葩linux,居然没有passwd命令. 生成密码摘要 openssl pass ...

  7. Navicat Premium 将sqlserver 数据库 导入mysql 中

    1.新建 MySQL 数据库  2.  3 4 5 6 7 8 9一直点击下一步 10 成功

  8. python 27 获取时区转换后的时间

    python3的datetime有timezone属性,这里介绍python2.7环境下,获取时区转换后的时间. 利用第三方插件,pytz,没有安装的话安装一下. #!/usr/bin/env pyt ...

  9. linux进程端口防火墙

    进程端口: 1.netstat –apn :查看所有的进程和端口使用情况 2.查看8080端口是否被占用 [root@localhost bin]# lsof -i:8080 3.查看防火墙开放的端口 ...

  10. 【Selenium-WebDriver自学】Selenium-IDE不同的浏览器(八)

    ==================================================================================================== ...