一文弄懂String的所有小秘密
云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!
简介
String是java中非常常用的一个对象类型。可以说java中使用最多的就是String了。那么String到底有哪些秘密呢?接下来本文将会一一讲解。
String是不可变的
String是不可变的,官方的说法叫做immutable或者constant。
String的底层其实是一个Char的数组。
所有的String字面量比如"abc"都是String的实现。
考虑下面的赋值操作:
对于java虚拟机来说,"abc"是字符串字面量,在JDK 7之后,这个字符串字面量是存储在java heap中的。而在JDK 7之前是有个专门的方法区来存储的。
有了“abc”,然后我们将“abc” 赋值给a和b。
可以看到这里a和b只是java heap中字符串的引用。
再看看下面的代码发生了什么:
首先在java heap中创建了“abc”,然后调用String的构造函数:
在构造函数中,String将底层的字符串数组赋值给value。
因为Array的赋值只是引用的赋值,所以上述new操作并不会产生新的字符串字面值。
但是new操作新创建了一个String对象,并将其赋值给了c。
String的不可变性还在于,String的所有操作都会产生新的字符串字面量。原来的字符串是永远不会变化的。
字符串不变的好处就在于,它是线程安全的。任何线程都可以很安全的读取字符串。
传值还是传引用
一直以来,java开发者都有这样的问题,java到底是传值还是传引用呢?
我想,这个问题可以从两方面来考虑。
首先对于基础类型int,long,double来说,对他们的赋值是值的拷贝。而对于对象来说,赋值操作是引用。
另一方面,在方法调用的参数中,全部都是传值操作。
我们看上面的例子,上面的例子输出ab。因为x是对“ab”的引用,但是在change方法中,因为是传值调用,所以会创建一个新的x,其值是“ab”的引用地址。当x被重新赋值之后,改变的只是拷贝之后的x值。而本身的x值是不变的。
substring() 导致的内存泄露
第一次看到这个话题,大家可能会很惊讶,substring方法居然会导致内存泄露?这个话题要从JDK 6开始讲起。
我们先看下JDK 6的实现:
可以看到,JDK 6的substring方法底层还是引用的原始的字符串数组。唯一的区别就是offset和count不同。
我们考虑一下下面的应用:
虽然最后我们将String赋值为null,但是subString仍然引用了最初的string。将不会被垃圾回收。
在JDK 7之后,String的实现发送了变化:
Arrays.copyOfRange将会拷贝一份新的数组,而不是使用之前的数组。从而不会发生上面的内存泄露的问题。
总结
虽然String是我们经常使用的对象,但是里面的原理还是值得我们了解的。
【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK
原文发布时间:2020-05-08
本文作者:flydean
本文来自:“掘金”,了解相关信息可以关注“掘金”
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
iOS开发——Block内存管理实例分析
说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下。 存储域 首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型: NSGlobalBlock NSStackBlock NSMallocBlock 从字面意思上大家也可以看出来1、NSGlobalBlock是位于全局区的block,它是设置在程序的数据区域(.data区)中。2、NSStackBlock是位于栈区,超出变量作用域,栈上的Block以及 ____block__变量都被销毁。3、NSMallocBlock是位于堆区,在变量作用域结束时不受影响。 注意:在 ARC 开启的情况下,将只会有 NSConcreteGlobalBlock 和 NSConcreteMallocBlock 类型的 block。 作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:413038000,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长! 推荐...
- 下一篇
hmtool 1.6.2 已发布,新增数据加解密
hmtool-ext-interchan 是一个基于hmtool & springboot融合的工具包、将hmtool和springboot|springcloud无缝接入、 包含springboot、springcloud相关对接以及演示demo配套。以便使用者更能快速得开发开展业务。不限制使用人群。商业等。demo版包含权限相关、日志记录等相关操作。 新特性 1:swagger header添加版本号管理 2:处理返回字符串多双引号问题(jackson) 3:提供数据加解密、敏感配置(可自定义实现、目前参数不支持对象、列表、map形式、引反射性能过低暂不考虑、请自行通过统一String来自定义实现对应特殊场景) 案例说明 配置 加解密代码 测试
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装