String是java最常的类,但它不是基础类型--因而内存的堆栈中它是以地址的形式保存.而它又是一个很特殊引用类型:类的声明是final,它是不能被继承的:
1 public final class String implements java.io.Serializable, Comparable<String>, CharSequence
String的主要属性:
1 private final char value[]; //String本质就是Char数组 2 private final int offset; //偏移位
3 private final int count; //就是Sting的length 4 private int hash; //hash码
StringBuffer的重要属性:
1 char value[]; 2 int count;
非常好!String的属性基本都是final类型,这应该就是Think In Java里的恒常性的关键所在.
对于final我们可以这样理解:
- 若变量是基本类型则它的值是不能变的。
- 若变量是对象则它的索引指向(在堆栈中)不可变,而只可能改变索引指定的对象(堆中)内的值。
而由于String内部变量是Final所以String的变量的索引指向不能变,而Char数组又是长度固定(String的改变往往带来长度的变化)。所以对String的改变不能将原来的String改变(原来的String的value指定被锁死),而只能重新返回一个新的String.这就是String与其他普通对象的重要区别---对其任何的本质上的改变都不会改变对象本身,而是返回一个新的对象.
StringBuffer由于不是final因而对StringBuffer的值改变只需要将类里的value[]的指向重新定向即可而不用重新new一个StringBuffer返回
String的构造器
1 public String() 2 { 3 offset = 0; 4 count = 0; 5 value = new char[0];//这个为什么不设置为null? 感觉是由于String有"+"操作,而null不可能有"+"操作 6 }
String的equals方法---由于char本质是数字因而直接==比较。
1 public boolean equals(Object obj) 2 { 3 if(this == obj) 4 return true; 5 if(obj instanceof String) 6 { 7 String s = (String)obj; int i = count; 8 if(i == s.count) 9 { 10 char ac[] = value; char ac1[] = s.value; 11 int j = offset; int k = s.offset; 12 while(i-- != 0) //值得学习 非常的精巧 13 if(ac[j++] != ac1[k++]) 14 return false; 15 return true; 16 } 17 } 18 return false; 19 }
在看完string源码后感觉String的本质就是Char[],他所有的方法都围绕着数组.而且虽然String有大量的方法不过一般背后都有一个通用方法,而其他方法都是调用这个通用方法实现的.而这里感觉最好的就是:
while(i-- != 0)
简直精巧极了!这可能就是代码的优雅.
总结:想看String的源码就是因为Think In Java所说的恒常性.而String的实现比较简单---重要变量为final形式
转:http://wsckw5.iteye.com/blog/553862
参考:http://blog.csdn.net/hkendless/article/details/7801656 String源码