new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,才
分配的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始
化,构造方法返回后,对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这
个引用操纵这个对 象。
clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调
用 clone 方法 的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之
后,clone 方法返回,一个新的相同的 对象被创建,同样可以把这个新对象的引用发布到外部。
new 对象的过程
类模板
public class pojo {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
创建对象
pojo pojo1=new pojo();
System.out.println(pojo1);//打印对象内存地址
结果
clone.pojo@3830f1c0
clone 对象的过程
想要将某个对象复制一份,称为对象的克隆技术。
在Object类汇总存在一个clone()方法:
protected Object clone() throws CloneNotSupportedException
如果某个类的对象想被克隆,则对象所在的类必须实现Cloneable接口。
此接口没有定义任何方法,是一个标记接口
具体代码实现:
/实现Cloneable接口,不用传参
public class pojo implements Cloneable {
//对象属性
private String name;
private int age;
//get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
main方法:
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
pojo pojo1=new pojo();
System.out.println("new对象的地址 "+pojo1);//打印对象内存地址
pojo pojo3 = (pojo) pojo1.clone();System.out.println("clon对象的地址 "+pojo3);//打印对象内存地址
}
运行结果
new对象的地址 clone.pojo@3830f1c0
clon对象的地址 clone.pojo@39ed3c8d
说明:原对象A 复制给 对象B后 引用地址已经发生变换 不再是同一个对象
复制对象和复制引用的区别
public class main {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
//new 一个新对象
pojo pojo1=new pojo();
//打印对象内存地址
System.out.println("new对象 pojo1 的地址 "+pojo1);
//将pojo2的对象引用指向pojo1
pojo pojo2=pojo1;
//打印对象内存地址
System.out.println("引用对象 pojo2 指向的地址 "+pojo2);
//将pojo2对象复制给pojo3对象
pojo pojo3 = (pojo) pojo1.clone();
//打印对象内存地址
System.out.println("clon复制对象 pojo3 的地址 "+pojo3);
}}
提问: 当pojo pojo2=pojo1;;执行之后, 是创建了一个新的对象吗? 首先看打印结果:
new对象 pojo1 的地址 clone.pojo@3830f1c0
引用对象 pojo2 指向的地址 clone.pojo@3830f1c0
clon复制对象 pojo3 的地址 clone.pojo@39ed3c8d
可以看出,打印的地址值是相同的,既然地址都是相同的,那么肯定是同一个对象。pojo1 和 pojo2 只是引用而已,他们都指向了一个相同的对象 。 可以把这种现象叫做引用的复制。上面代码执行完成之后, 内存中 的情景如下图所示:
而
pojo pojo3 = (pojo) pojo1.clone();
代码是真真正正的克隆了一个对象。
从打印结果可以看出,两个对象的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新 的引用变量。
内存中的情景如下图所示: