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

对于这样的常识,不再赘述。

首先String类是final类,为什么定义成final形式呢?

简单点说,对于如此高频率被使用的数据类型,设计者们认为已经设计的足够优秀了,不需要被继承,否则胡乱继承重写可能会降低程序的性能。

正如标题所述,既然深入,那我们就挖下String在jvm层面的小动作。

先解释字面量创建的形式:

当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。

如下所示:

String str1 = "hello" ;

当我们第一次创建的时候,这里我们认为没有内容为hello的对象存在。JVM通过字符串常量池查找不到内容为hello的字符串对象存在,那么会创建这个字符串对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量str1

如果接下来有这样一段代码

String str2 = "hello" ;

同样JVM还是要检测这个字面量,JVM通过查找字符串常量池,发现内容为”hello”字符串对象存在,于是将已经存在的字符串对象的引用返回给变量str2。注意这里不会重新创建新的字符串对象。

验证是否为str1和str2是否指向同一对象,我们可以通过这段代码

System.out.println(str1 == str2);

结果为true。

第二种使用new创建:

String str3 = new String("hello");

当我们使用了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象的引用,新的字符串对象都会创建。因此我们使用下面代码测试一下,

String str3 = new String("hello");

System.out.println(str1 == str3);

结果为false。说明这两个引用指向不同的对象。

intern

对于上面使用new创建的字符串对象,如果想将这个对象的引用加入到字符串常量池,可以使用intern方法。

调用intern后,首先检查字符串常量池中是否有该对象的引用,如果存在,则将这个引用返回给变量,否则将引用加入并返回给变量。

String str4 = str3.intern();

System.out.println(str4 == str1);

结果为true。

疑难问题

前提条件?

字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。

引用 or 对象

字符串常量池中存放的时引用还是对象,这个问题是最常见的。字符串常量池存放的是对象引用,不是对象。在Java中,对象都创建在堆内存中。字符串常量池存在于堆内存中的永久代

优缺点

字符串常量池的好处就是减少相同内容字符串的创建,节省内存空间。

如果硬要说弊端的话,就是牺牲了CPU计算时间来换空间。CPU计算时间主要用于在字符串常量池中查找是否有内容相同对象的引用。不过其内部实现为HashTable,所以计算成本较低。

GC回收?

因为字符串常量池中持有了共享的字符串对象的引用,这就是说是不是会导致这些对象无法回收?

首先问题中共享的对象一般情况下都比较小。据我查证了解,在早期的版本中确实存在这样的问题,但是随着弱引用的引入,目前这个问题应该没有了。

intern使用?

关于使用intern的前提就是你清楚自己确实需要使用。比如,我们这里有一份上百万的记录,其中记录的某个值多次为美国加利福尼亚州,我们不想创建上百万条这样的字符串对象,我们可以使用intern只在内存中保留一份即可。

总有例外?

你知道下面的代码,会创建几个字符串对象,在字符串常量池中保存几个引用么?

String test = "a" + "b" + "c";

答案是只创建了一个对象,在常量池中也只保存一个引用。我们使用javap反编译看一下即可得知。

实际上在编译期间,已经将这三个字面量合成了一个。这样做实际上是一种优化,避免了创建多余的字符串对象,也没有发生字符串拼接问题。

以上这篇老生常谈Java String字符串(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

java string返回_老生常谈Java String字符串(必看篇)相关推荐

  1. java 动态编译_老生常谈Java动态编译(必看篇)

    一.动态编译简介 new创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类. 一百个类,有一个类错了,都无法编译. 通过动态加载类可以解决该问题 二.代码实例 2.1 OfficeBette ...

  2. java void 返回_关于java:Void方法不能返回void方法的值?

    我不介意我不明白,但我想知道为什么会这样: void something(String a) { return hi(); } void hi() { return; } 奇怪的是,hi()的返回类型 ...

  3. java 异步返回_在Java中使用异步后,主方法如何返回异步中得到的值?

    慕莱坞5435954 我没有研究过 RxJava,不过之前团队里面做 Android 的开发的同事说是很好用.1 楼给了一种使用 Future 的方案,但是很抱歉 Future 是一种异步阻塞式的AP ...

  4. 老生常谈重放攻击的概念(必看篇)

     重放攻击的概念 根据百科的解释:重放攻击(Replay Attacks)又称重播攻击.回放攻击或新鲜性攻击(Freshness Attacks),是指攻击者发送一个目的主机已接收过的包,来达到欺 ...

  5. java 中传输文件的代码_java文件上传Demo(必看篇)

    说到文件上传我们要做到: 1.引入两个包:commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar 2.将form改为上传文件模式:enctype=" ...

  6. Java基础通信_Java网络通信基础编程(必看篇)

    方式一:同步阻塞方式(BIO): 服务器端(Server): package com.ietree.basicskill.socket.mode1; import java.io.IOExceptio ...

  7. 一个牛人给Java初学者的建议(必看篇)

    给初学者之一:浅谈Java及应用学java 从不知java为何物到现在一个小小的j2ee项目经理虽说不上此道高手,大概也算有点斤两了吧每次上网,泡bbs逛论坛,没少去java相关的版 面总体感觉初学者 ...

  8. python的难点_初学python的操作难点总结(新手必看篇)

    如下所示: 1 在cmd下 盘与盘之间的切换 直接 D或d: 就好 2 查找当前盘或者文件下面的目录 直接 dir 3 想在一个盘下进去一个文件夹,用cd空格目标文件 cd p 4 写文件的第一个字母 ...

  9. python新手入门总结_初学python的操作难点总结(新手必看篇)

    如下所示: 1 在cmd下 盘与盘之间的切换 直接 D或d: 就好 2 查找当前盘或者文件下面的目录 直接 dir 3 想在一个盘下进去一个文件夹,用cd空格目标文件 cd p 4 写文件的第一个字母 ...

  10. java string()函数_转载java String.split()函数的用法详解

    转载java String.split()函数的用法详解 如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!在java.lang包中有String.split()方法的原型是: p ...

最新文章

  1. OpenAPI使用(swagger3),Kotlin使用swagger3,Java使用swagger3,gradle、Maven使用swagger3
  2. P2949 [USACO09OPEN]Work Scheduling (后悔法,贪心)难度⭐⭐⭐
  3. 测试驱动开发是否是一种强迫症?
  4. 浅析如何从比值得出网站优化效果的好坏?
  5. KindEditor上传的图片显示在jsp页面上时调整布局
  6. golang goroutine协程概念及入门:轻量级线程(或用户态线程)
  7. 51nod 1270 数组的最大代价 思路:简单动态规划
  8. UNIX/Linux系统管理技术手册(1)----脚本和shell
  9. yolox-keras的源码,超越YOLOv5,可以用于训练自己的模型
  10. 005 Aspectj的引入
  11. node js npm grunt安装,elasticsearch-head 5.X安装
  12. C/C++[codeup 2025]比较字符串
  13. 计算机显卡驱动全部卸载,如何卸载显卡驱动重新安装?Win10卸载显卡驱动+重装显卡驱动的方法...
  14. 用Python批量修改文件名称
  15. linux bind日志级别,Bind日志配置。
  16. 用python画圆角矩形_如何用OpenCV绘制圆角矩形(带圆角的矩形)?
  17. 推荐几个常用常玩的小游戏网址包括4399.com
  18. 网页怎么与服务器进行连接,如何实现网页与服务器的连接
  19. docker部署SRS实时视频服务器,rtmp推流,用WebRTC播放
  20. 尼尔机器人技能快捷键_尼尔机械纪元出招表及招式使用技巧 尼尔机械纪元技能怎么用...

热门文章

  1. STL总结笔记(实用 / 比赛)
  2. 计算机硬盘 u盘和光盘属于,磁盘U盘光盘的区别
  3. python字符串左_Python去除字符串左边指定字符
  4. 服务器位置设置,服务器部署位置
  5. 机器人学(机构学)笔记
  6. 2019年宁波高职技能考计算机,2019年宁波职业技术学院高职提前招生考试综合素质测试大纲...
  7. 马尔科夫决策过程(MDP) : BlackJack (MC-On Policy)
  8. 机器学习- 吴恩达Andrew Ng Week7 知识总结Support Vector Machines
  9. 计算机组成与人体类比,2020年安徽公务员考试真题模拟:类比推理(7.13)
  10. js导出的xlsx无法打开_遇到U盘无法打开,属性显示0字节这样的问题?数据该如何导出?...