码迷,mamicode.com
首页 > 其他好文 > 详细

关于String

时间:2019-10-11 23:08:05      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:设计   serial   改变   class   vat   创建   自动   地址   char   

1. String中什么是不可变的

2 .怎么实现的不可变

3.为什么要设计成不可变的

下面就来一起看一下这几个问题吧

 

一。String对象有两种创建方式,一种就是直接通过new  ,另一种一种就是直接赋值

String s1 = new String("abc");           String s2 = "abc";

一种是在堆中创建对象,一种实在常量池中创建对象(jdk1.7以后也放在堆中),然后由栈中的引用对象指向堆中的地址,

String s1 = s1+"abc";输出的s1是变成了"abcbc",但不过只是s1指向的堆内存地址发生了变化,之前的那个"abc"对象还是存在的,只不过没有人使用它了,一段时间后就会被GC自动回收掉;

其实只要明白栈中存储对象的引用,堆中存储对象实例,就能想清楚,堆内存中的对象是不会由于引用指向的改变而变化的,要想改变只能从内部着手,然而String并没有提供”setter“方法,

所以String对象的不可变,不管你是说长度不可变也好,内容不可变也好,总之就是对象一旦创建就是不可变,由于没有"setter"方法

不知到有没有跟笔者刚开始学的时候一样,总是弄不清楚s1.replace("a","f");要不要重新创建一个引用对象来保存这个新的字符串,现在可以肯定的告诉你“需要”,因为String对象不可变,猜也能猜到内部一定是创建一个新的对象来存储,不信的可以自己翻一下源码。

 

二。然后就来看一下String类是怎么实现的不可变,简单的理解可以认为没有”setter“方法供已操作

下面看一下String的源码

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
  ...
}
  • 可以看出String类被final修饰。String类不能被继承,所有的方法也就不能被重写
  • 其次它的存储单元char数组也被final修饰。代表这char数组一旦被赋值,就不能够再次改变,这里的改变是指的指针不能指向其他的内存地址,而其中的内容是可以发生变化的
  • 还有一点就是没有提供修改char数组中内容的方法 对于上一点,String本身并没有提供可以修改的方法

其实这三点就能够确保String对象的不可变性了。

三。那么为什么要对String有这样的设计呢?

1。字符串常量池的需要,常量池是为了减少字符串的创建,当常量池中有此字符串时,即 String str1 = "ABC", String str2 = "ABC",str1和str2会指向同一个地址,如果str1发生改变,会影响str2的值

2。安全考虑  String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。

3。hacode用到  String类被用这hashcode计算,String不可变能够缓存key的hash值从而不用每次都需要重新计算,减少性能开销。

关于String

标签:设计   serial   改变   class   vat   创建   自动   地址   char   

原文地址:https://www.cnblogs.com/zjgp/p/11638539.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!