黑马程序员【阅读源码理解String对象的不变性】

来源:互联网 发布:淘宝网店发展现状 编辑:程序博客网 时间:2024/04/29 08:11

------- android培训、java培训、期待与您交流! ----------

String的对象都有一个特性 ,就是不可变性,不可变是指String对象创建后,其值就不能再改变,代用String的任何方法修改字符串最后都会返回一个新的String对象,而对原String对象没有任何影响。下面通过解读源码和实例来进一步说明:

public class Test {public static void main(String[] args) {String s1="java";String s2="heima";String s11=s1.replace("a", "b");String s22=s2.replace("h", "H");//s1 s2的值不变System.out.println(s1);System.out.println(s2);//修改后返回的一个新String对象System.out.println(s11);System.out.println(s22);System.out.println(s1==s11);System.out.println(s2==s22);}}

运行结果:

java
heima
jbvb
Heima
false
false

可以看到,通过replace方法并没能改变s1和s2的值,而且最终返回了一个新的String对象。

为什么不能直接修改String的变量呢?看一下String类的源码就一目了然了。

package java.lang;public final class String    implements java.io.Serializable, Comparable<String>, CharSequence {    /**      *String字符串的本质是一个字符数组     *final限制了value引用是不可变的     *同时用private修饰,又没有提供setter和getter方法,     *最终决定了String类的不可变性     *     */    private final char value[];    //构造方法,创建一个长度为0的空字符数组    public String() {        this.value = new char[0];    }
但是String类确实提供一些可以修改字符串的方法,concat,substring, replace, replaceAll等,可是从上面的例子中可以看出,最终并没有改变原字符串的值,这是为什么?

   public String substring(int beginIndex) {        if (beginIndex < 0) {            throw new StringIndexOutOfBoundsException(beginIndex);        }        int subLen = value.length - beginIndex;        if (subLen < 0) {            throw new StringIndexOutOfBoundsException(subLen);        }        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);    }   public String concat(String str) {        int otherLen = str.length();        if (otherLen == 0) {            return this;        }        int len = value.length;        char buf[] = Arrays.copyOf(value, len + otherLen);        str.getChars(buf, len);        return new String(buf, true);    }    public String replace(char oldChar, char newChar) {        if (oldChar != newChar) {            int len = value.length;            int i = -1;            char[] val = value; /* avoid getfield opcode */            while (++i < len) {                if (val[i] == oldChar) {                    break;                }            }            if (i < len) {                char buf[] = new char[len];                for (int j = 0; j < i; j++) {                    buf[j] = val[j];                }                while (i < len) {                    char c = val[i];                    buf[i] = (c == oldChar) ? newChar : c;                    i++;                }                return new String(buf, true);            }        }        return this;    }
不用管以上方法具体怎么实现的,只看最后的返回值,可以知道,都是用修改后的临时数组new一个新的String 返回给程序。

String类是不可变(final)的,对String类的任何改变,都是返回一个新的String类对象.这样的话把String类的引用传递给一个方法,该方法对String的任何改变,对原引用指向的对象没有任何影响。

------- android培训、java培训、期待与您交流!

----------详情请查看:http://edu.csdn.net/heima

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 头发两天就油了怎么办 头发被剪的很丑怎么办 美发师年龄大了怎么办 青春期头发掉的厉害怎么办 剪了短发头发翘怎么办 4个月婴儿咳嗽怎么办 2个月婴儿咳嗽怎么办 5个月婴儿咳嗽怎么办 烫的内扣睡觉怎么办 站了一天腿疼怎么办 头发被剪得很丑怎么办 淹脖子破皮了怎么办 孩子胖脖子淹了怎么办 宝宝屁股破皮了怎么办 新生儿屁屁发红及烂怎么办 头发烫完太蓬松怎么办 头发烫的太卷了怎么办 烫了卷发很毛躁怎么办 烫发后头发干枯毛躁怎么办 烫完头发掉发怎么办 烫发掉发严重该怎么办 烫头发后掉头发怎么办 烫过头发后毛躁怎么办 烫了头发像大妈怎么办 头发烫了之后很毛躁怎么办 鳄龟爪子烂了怎么办 乌龟壳边缘烂了怎么办 乌龟拉绿色的水怎么办 小乌龟龟壳变软怎么办 鳄龟不待在水里怎么办 脖子整天黏黏的怎么办 有脊椎侧弯跳舞怎么办 落枕10天还不好怎么办 落枕十几天没好怎么办 肩一边高一边低怎么办 35岁无稳定工作怎么办 机械手表走的快怎么办 机械表发条紧了怎么办 两只乌龟互相咬怎么办? 乌龟鼻子摔烂了怎么办 剃刀龟脖子肿了怎么办