详解Java中的指针、引用及对象的clone(4)

2008-02-23 09:32:40来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

Clone中String和StringBuffer的区别
应该说明的是,这里不是着重说明String和StringBuffer的区别,但从这个例子里也能看出String类的一些与众不同的地方。
下面的例子中包括两个类,CloneC类包含一个String类型变量和一个StringBuffer类型变量,并且实现了clone()方法。
在StrClone类中声明了CloneC类型变量c1,然后调用c1的clone()方法生成c1的拷贝c2,在对c2中的String和StringBuffer类型变量用相应的方法改动之后打印结果:

package clone;
class CloneC implements Cloneable{
public String str;
public StringBuffer strBuff;
public Object clone(){
CloneC o = null;
try{
o = (CloneC)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return o;
}
}
public class StrClone {
public static void main(String[] a)
{
CloneC c1 = new CloneC();
c1.str = new String("initializeStr");
c1.strBuff = new StringBuffer
("initializeStrBuff");
System.out.println("before
clone,c1.str = " c1.str);
System.out.println("before
clone,c1.strBuff = " c1.strBuff);
CloneC c2 = (CloneC)c1.clone();
c2.str = c2.str.substring(0,5);
c2.strBuff = c2.strBuff.append
(" change strBuff clone");
System.out.println("=================================");
System.out.println("after
clone,c1.str = " c1.str);
System.out.println
("after clone,c1.strBuff = " c1.strBuff);
System.out.println("=================================");
System.out.println("after
clone,c2.str = " c2.str);
System.out.println
("after clone,c2.strBuff = " c2.strBuff);
}
}
/* RUN RESULT
before clone,c1.str = initializeStr
before clone,c1.strBuff = initializeStrBuff
=================================
after clone,c1.str = initializeStr
after clone,c1.strBuff =
initializeStrBuff change strBuff clone
=================================
after clone,c2.str = initi
after clone,c2.strBuff =
initializeStrBuff change strBuff clone
*
*/
打印的结果可以看出,String类型的变量好象已经实现了深度clone,因为对c2.str的改动并没有影响到c1.str!难道Java把Sring类看成了基本数据类型?其实不然,这里有一个小小的把戏,秘密就在于c2.str = c2.str.substring(0,5)这一语句。
实质上,在clone的时候c1.str与c2.str仍然是引用,而且都指向了同一个String对象。但在执行c2.str = c2.str.substring(0,5)的时候,它作用相当于生成了一个新的String类型,然后又赋回给c2.str。
这是因为String被Sun公司的工程师写成了一个不可更改的类(immutable class),在所有String类中的函数都不能更改自身的值。下面给出很简单的一个例子:

package clone; public class StrTest
{
public static void main(String[] args)
{
String str1 = "This is a test for immutable";
String str2 = str1.substring(0,8);
System.out.println("print str1 : " str1);
System.out.println("print str2 : " str2);
}
}
/* RUN RESULT print str1 :
This is a test for immutable print str2 :
This is */
例子中,虽然str1调用了substring()方法,但str1的值并没有改变。类似的,String类中的其它方法也是如此。当然如果我们把最上面的例子中的这两条语句

c2.str = c2.str.substring(0,5);
c2.strBuff = c2.strBuff.append
(" change strBuff clone");
改成下面这样:

c2.str.substring(0,5);
c2.strBuff.append
(" change strBuff clone");
去掉了重新赋值的过程,c2.str也就不能有变化了,我们的把戏也就露馅了。但在编程过程中只调用

c2.str.substring(0,5);
语句是没有任何意义的。
应该知道的是在Java中所有的基本数据类型都有一个相对应的类,象Integer类对应int类型,Double类对应double类型等等,这些类也与String类相同,都是不可以改变的类。
也就是说,这些的类中的所有方法都是不能改变其自身的值的。这也让我们在编clone类的时候有了一个更多的选择。同时我们也可以把自己的类编成不可更改的类。

上一篇: J2EE修炼之四书五经
下一篇: JAVA对象序列化保存为XML文件的工具类

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:使用J2ME技术实现简单的动画(附代码实现)

下一篇:Beanutils (1)