java字符串不可变性及JDK6和JDK7中 substring 的原理及区别

字符串的不可变性

一旦一个String对象被创建并被赋值(初始化)这个对象的值就不会变化;

一旦一个String对象在内存中创建,它将是不可改变的,所有的String类中方法并不是改变String对象自己,而是重新创建一个新的String对象。

例如:

public class Reverse {
    public static void main(String[] args)
    {
        String c1=new String("abc");
        String c2=new String("abc");
        String c3=c1;//将c1对象的引用赋值给c3

        System.out.println("c1==c2:"+  (c1==c2)); //false,虽然两个对象的值相同,但是对象在不同的内存空间,是两个不同的对象引用,所以为false;

        System.out.println("c1.equals(c2):"+c1.equals(c2));//true,equals方法用于比较值,所以结果为true;

        System.out.println("c3==c1:"+(c3==c1));//true
        System.out.println("c1.equals(c3):"+c1.equals(c3));//true
        c1="han";// 并不是改变了原有对象的值,而是创建了一个新的字符串对象,这个对象的值是han,并把这个对象的引用赋值给了c1。

        System.out.println(c1+"   "+c3);
        System.out.println(""+(c3==c1));//false  c1="han" c3="abc"
    }
}

 

 

JDK6和JDK7中 substring 的原理及区别

substring()的作用就是截取父字符串的某一部分,substring(int beginIndex, int endIndex);

JDK6中,String是通过字符数组实现的,String类包含三个成员变量:char value[], int offset,int count。他们分别用来存储真正的字符数组,数组的第一个位置索引以及字符串中包含的字符个数。

JDK7中,String类去掉了属性offset和count,因为截取后创建新的数组,不需要offset和count两个属性;

JDK6:在原来数组的基础上通过偏移量offset和数量count决定新的字符串(如图和代码块);

 

JDK7:copy并截取部分数组作为新的字符串;

JDK6实现:

JDK7实现:

//JDK 6
String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

public String substring(int beginIndex, int endIndex) {
    //check boundary
    return  new String(offset + beginIndex, endIndex - beginIndex, value);
}
//JDK 7
public String(char value[], int offset, int count) {
    //check boundary
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
    //check boundary
    int subLen = endIndex - beginIndex;
    return new String(value, beginIndex, subLen);
}

总结:

如果原来的字符串被截取后,还是会经常使用,并不需要释放资源,那么比较适合使用JDK6中的方式;

如果原本很长的字符串,需要的只是一小段字符序列,原来的字符串不再被使用,那么比较适合使用JDK7中的方式;

在JDK6中,虽然使用的字符串较短,但是这个非常长的字符数组一直在被引用,所以无法被回收,就可能导致内存泄露。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值