看java String类的不可变性

  常遇到面试说,String为啥被设计成不可变的。看了下源码,说下个人看法:

1、String的不可变   

String a="hello";
a="hello world";

a 指向内存中常量池中"hello";后又被赋值为"hello world"。有人说这不是变化了吗?其实不然。原内容"hello"仍然存在于内存常量池中,a 指向了新的地址,常量池中“hello world”。

     这种a 所指向的内存地址发生变化,原地址所对应的值没有发生任何变化的现象,即为String 的不可变性。

2、String 源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

从源码可以看出,首先 类被final修饰,也就是说不可以被继承,其次存储String 值的value 数组变量被封装在了类内部,不被外界访问,这就是为什么String 不可变的真实原因。

3、好处

    >java 语言具有内存共享的机制,String 对象共享又是很重要的一部分-“常量池”。因为常量池的存在,程序可以节省大量的内存开支。

   > 正是因为String 的不可变性,保证了程序的安全性。由于共享机制的存在,假如String 可以变化,那么就是说被共享的任意字符串,都可能被程序其他部分修改,那么这点是相当不安全的。

> 不可变对象不可写,所以多线程并发时,可以保证线程安全

4、String 类的衍生,StringBuffer 和StringBuilder 为什么可变?

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
....


 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

从两个类的定义开头,我们可以看到,两个类也都被定义为了final 的,那么为什么却可以被改变呢?从定义中,我们可以看到,二者共同的父类为

abstract class AbstractStringBuilder implements Appendable, CharSequence {

    /**
     * The value is used for character storage.
     */
    char[] value;

可见,二者存储值的成员变量,value 是可以被子类对象通过append方法来进行修改的。

>当字符长度,不超过value 初始长度时,将通过 value[index]= ...的方式填充value的值。此时,变量value数组对象引用地址没有变化,但是数组内容发生了变化。

>当长度超过初始长度时,将会通过System.copyOf方法,将value所指向的内存中的值拷贝至新的更大容量的数组对象中。

   原数组对象,将被垃圾回收器回收。此时value整个引用对象发生变化,原数组对象值在新数组对象中得到了追加。

 public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值