黑马程序员【阅读源码理解String对象的不变性】
2014-07-09 16:51
405 查看
------- android培训、java培训、期待与您交流! ----------
String的对象都有一个特性 ,就是不可变性,不可变是指String对象创建后,其值就不能再改变,代用String的任何方法修改字符串最后都会返回一个新的String对象,而对原String对象没有任何影响。下面通过解读源码和实例来进一步说明:
运行结果:
java
heima
jbvb
Heima
false
false
可以看到,通过replace方法并没能改变s1和s2的值,而且最终返回了一个新的String对象。
为什么不能直接修改String的变量呢?看一下String类的源码就一目了然了。
String类是不可变(final)的,对String类的任何改变,都是返回一个新的String类对象.这样的话把String类的引用传递给一个方法,该方法对String的任何改变,对原引用指向的对象没有任何影响。
------- android培训、java培训、期待与您交流!
----------详情请查看:http://edu.csdn.net/heima
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
相关文章推荐
- 字符 深入理解java String 对象的不可变性
- 深入理解java String 对象的不可变性
- 深入理解java String 对象的不可变性
- 黑马程序员_java面向对象相关 个人理解
- String l数据对象的Hash Code值的理解
- [Chrome源码阅读] 理解Browser进程
- 奋斗黑马程序员----Java之String对象
- 黑马程序员_学习记录12:String、StringBuffer、基本数据类型对象包装类
- 理解对象/关系持久 hibernation 在行动阅读(一)
- [Chrome源码阅读] 理解Chrome导航网址的流程及render进程启动模式
- [Lua源码阅读] 理解Lua的object
- Three.js源码阅读笔记(基础的核心Core对象)
- jquery源码阅读知识储(8)Javascript引用和作用域的理解
- 黑马程序员——C#对面向对象编程的理解
- 黑马程序员_学习笔记2交通灯系统中面向对象思想的理解以及工厂模式的应用
- [Chrome源码阅读] 理解ObserverList类的实现技巧
- 个人对Java中String对象的传递的理解(错误之处,请给与纠正,
- JDK源码阅读之二-----String
- [Chrome源码阅读] 理解Chrome的smart pointer
- 黑马程序员__String_StringBuffer_基本数据类型对象包装类