打字猴:1.7004419e+09
1700441900
1700441901 大儿子的父亲是父亲
1700441902
1700441903 小儿子的父亲是父亲
1700441904
1700441905 这很正确,没有问题。突然有一天,父亲心血来潮想让大儿子去认个干爹,也就是大儿子的父亲名称需要重新设置一下,代码如下:
1700441906
1700441907 public static void main(String[]args){
1700441908
1700441909 //定义父亲
1700441910
1700441911 Person f=new Person(“父亲”);
1700441912
1700441913 //定义大儿子
1700441914
1700441915 Person s1=new Person(“大儿子”,f);
1700441916
1700441917 //小儿子的信息是通过大儿子拷贝过来的
1700441918
1700441919 Person s2=s1.clone();
1700441920
1700441921 s2.setName(“小儿子”);
1700441922
1700441923 //认干爹
1700441924
1700441925 s1.getFather().setName(“干爹”);
1700441926
1700441927 System.out.println(s1.getName()+“的父亲是”+s1.getFather().getName());
1700441928
1700441929 System.out.println(s2.getName()+“的父亲是”+s2.getFather().getName());
1700441930
1700441931 }
1700441932
1700441933 上面仅仅修改了加粗字体部分,大儿子重新设置了父亲名称,我们期望的输出是:将大儿子父亲的名称修改为干爹,小儿子的父亲名称保持不变。下面来检查一下结果是否如此:
1700441934
1700441935 大儿子的父亲是干爹
1700441936
1700441937 小儿子的父亲是干爹
1700441938
1700441939 怎么回事,小儿子的父亲也成了“干爹”?两个儿子都没有,岂不是要气死“父亲”了!出现这个问题的原因就在于clone方法,我们知道所有类都继承自Object, Object提供了一个对象拷贝的默认方法,即上面代码中的super.clone方法,但是该方法是有缺陷的,它提供的是一种浅拷贝方式,也就是说它并不会把对象的所有属性全部拷贝一份,而是有选择性的拷贝,它的拷贝规则如下:
1700441940
1700441941 (1)基本类型
1700441942
1700441943 如果变量是基本类型,则拷贝其值,比如int、float等。
1700441944
1700441945 (2)对象
1700441946
1700441947 如果变量是一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在Java中是很疯狂的,因为它突破了访问权限的定义:一个private修饰的变量,竟然可以被两个不同的实例对象访问,这让Java的访问权限体系情何以堪!
1700441948
1700441949 (3)String字符串
[ 上一页 ]  [ :1.7004419e+09 ]  [ 下一页 ]