Java深浅拷贝
深浅拷贝 Java
1. 前提
-
深浅拷贝的前提是当拷贝一个对象时,即生成一个新的对象时。
-
生成一个新的对象,主要有以下工作
-
内存分配一块和被拷贝的类一样的区域
-
划分字段,方法的使用区域
-
将被拷贝类内存里的内容搬到指定区域
-
2. 怎么搬?
- 前提中说到把被拷贝类内存里的内容搬到新的区域,怎么搬呢?我的理解就是简单的赋值。
```java
class Person{
public int age;
public String name;
public Person(){
}
public Person(int m_age, String m_name){
age = m_age;
name = m_name;
}
}
// 拷贝的过程类似如下
Person per = new Person(12, "Fizz");
Person oth = new Person();
oth.age = per.age;
oth.name = per.name
```
- 简单的赋值有问题吗?对于引用型变量和基本数据类型有啥不同?
1.对于基本数据类型,=相当于赋值内容,而对于引用变量,= 只是传递对象的地址。
2. 所以oth.name 和per.name共用一个String对象。而对于age字段,是基本数据类型,所以oth.age和per.name各自拥有一个int值。
3. 结论
- 在拷贝被过程中,对于引用型的字段,只是简单的赋值操作,而没有生成一个新的对象,叫做浅拷贝。
- 在拷贝过程中,对于引用型的字段,生成一个一个新的对象,区别在于对象地址不同了,叫做深拷贝。
4. Java如何实现拷贝
-
Object类具有一个clone的native方法,c++实现。
-
被拷贝的类实现Cloneable接口,并重写clone方法即可。
package com; import java.util.Objects; public class TestStr { public static void main(String[] args) { Person per = new Person("fizz", 5); Person oth = per.clone(); System.out.println(per==oth);// false System.out.println(per.name == oth.name);// false } } class Person implements Cloneable{ String name; int age; Person(String m_name, int m_age){ name = m_name; age = m_age; } @Override public Person clone(){ try{ Person cloneob = (Person) super.clone();//spuer.clone()最终会到达Object.clone()。浅拷贝,对象内部成员只是简单的赋值,c++实现。 cloneob.name = new String(this.name);//拷贝字符串对象 return cloneob; }catch (CloneNotSupportedException e){ System.out.println(e); } return null; } }
5. 思考
- 这个问题其实就是c++中赋值构造函数,实现一个对象的拷贝,看来c++还是得复习复习。