读书人

深入String部类

发布时间: 2012-12-21 12:03:49 作者: rapoo

深入String类型
曾经有人问我一个问题,往一个没有返回值的方法中传一个非静态、非final的String类型参数,在方法中改变它,为什么出了方法还是原来的值?
String类型我们用的最常见的莫过于此种构造函数;
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}

你发现了什么?其实我们用String类型本质上还是用char类型。java中的传递参数都可以看成传值,因为java不像C中有指针。既然是传值那么就不能改变这个值,只能从栈中拷贝一份过去。这个拷贝的是引用,应为栈中不可能有对象。在改变参数法则中不能改变对象本身只能改变对象下的子节点值,若子节点也是对象则继续找他的子节点,直到基本类型为止。看到了吧。String类型其实就是char难道你能改变吗?已经到了基本类型就不能在改变。由此类推Long、Integer、、、等包装类型都是这种特点。

又一次又有人问我:
为什么
String a="ss";
String b="ss";
a==b 返回true
a.equals(b) 返回true

String c=new String("ss");
String d=new String("ss");
c==d 返回false
d.equals(d) 返回true

这种问题有很多人都知道但是要让你解释为什么还真是让人头痛的。
String a="ss"; 这是有一系列的动作组成的。首先“ss”会看在String的常量池中有没有一个"ss",如果没有就放一个进去,如果有就把a引用所引用的对象指向常量池中的对象,否则把"ss",放进常量池中并把这个地址给a引用。所以a、b都代表的是一个地址,一个对象。而new呢?大家都知道new是创建性对象,分配新空间。没错是要分配新空间,但是他的空间在堆里面一个区域里,他和常量池不是在一个区域。所以你new一个是一个新对象,在new一个还是一个新对象。c==d返回false就不难解释了。d.equals(d) 返回true也是理所当然了。
































读书人网 >编程

热点推荐