我们知道clone方法在Java中是一个复制对象的方法,那么Java有几种创建对象的方式呢?通过new关键字创建一个对象
通过clone方法复制一个对象
复制引用和通过clone方法复制对象有什么不同?
在分析这个问题之前我们先了简单了解下Java中JVM的内存分配,Java的JVM的内存分为3个区:堆(Heap)、栈(Stack)和方法区(Method Area)。
接下来通过两个实例进行分析
实例1
Dog dog = new Dog("Odie");
Dog dog1 = dog;
System.out.println(dog);
System.out.println(dog1);
执行 Dog dog1 = dog;是生成一个新对象还是复制的一个引用?
打印结果:
Dog@6132b73b
Dog@6132b73b
通过打印结果我们看到,执行 Dog dog1 = dog; 后打印的地址是相同的,则执行Dog dog1 = dog;是复制的一个引用。
JVM内存分配情况
实例2
Dog dog = new Dog("Odie");
Dog dog1 = (Dog) dog.clone();
System.out.println(dog);
System.out.println(dog1);
打印结果:
Dog@6132b73b
Dog@489bb457
通过打印结果我们看到,执行 Dog dog1 = (Dog) dog.clone(); 后打印的地址是不相同的,则执行Dog dog1 = (Dog) dog.clone();是创建了一个新对象。
JVM内存分配情况
使用clone方法中常提到的深拷贝和浅拷贝
实例3 深拷贝
public class Main {
static class Body implements Cloneable{
public Body() {}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
Body body = new Body();
Body body1 =(Body) body.clone();
System.out.println("是否是深拷贝 " + (body != body1) );
}
}
在执行Body body1 =(Body) body.clone();重新创建了一个新对象而不是复制的一个引用,这种情况叫深拷贝。
实例4 浅拷贝
public class Main {
static class Body implements Cloneable{
public Body() {}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
Body body = new Body();
Body body1 = body;
System.out.println("是否是深拷贝 " + (body != body1) );
}
}
在执行Body body1 = body;拷贝的是一个引用,这种情况叫浅拷贝。
通过实例3和实例4得出一个结论:如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法。
总结:
虽然clone方法平时项目不是很常用,但是通过clone方法去深入了解JVM的内存结构和运行机制,也是写这篇文章的目的。
谢谢阅读!