一、Java中的赋值
java中对象的赋值是通过对象的引用的形式进行赋值。
1.1 关于赋值的实现
创建Person类
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}测试赋值
@Test
public void testSimpleDemo(){
Person p1 = new Person();
p1.setName("tom");
p1.setAge(21);
Person p2 = p1;
System.out.println(p1); //Person{name='tom', age=21}
System.out.println(p2); //Person{name='tom', age=21}
System.out.println(p1 == p2); //true
}
二、Java中clone的实现
实现clone要让实体类实现Cloneable接口
再重写接口中的clone方法
实现Cloneable接口
public class Person implements Cloneable {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试
@Test
public void testShallowClone() throws CloneNotSupportedException {
Person p1 = new Person();
p1.setName("tom");
p1.setAge(21);
Person p2 = (Person) p1.clone();
System.out.println(p1); //Person{name='tom', age=21}
System.out.println(p2); //Person{name='tom', age=21}
System.out.println(p1 == p2); //false
}
注意:如果实体类中添加了引用类型的对象
创建Address类
public class Address {
private String type;
private String name;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Address{" +
"type='" + type + '\'' +
", name='" + name + '\'' +
'}';
}
}添加Address属性
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}测试
@Test
public void testShallowClone() throws CloneNotSupportedException {
Address address = new Address();
address.setType("home");
address.setName("北京");
Person p1 = new Person();
p1.setName("tom");
p1.setAge(21);
p1.setAddress(address);
Person p2 = (Person) p1.clone();
p2.getAddress().setType("office");
System.out.println(p1); //Person{name='tom', age=21, address=Address{type='office', name='北京'}}
System.out.println(p2); //Person{name='tom', age=21, address=Address{type='office', name='北京'}}
System.out.println(p1 == p2); //false
}
这里就发现了问题,我只在p2对象中将type属性修改为office,可是p1也跟着改变了,该如何解决呢?
三、clone问题的解决
要解决问题首先要知道深拷贝和浅拷贝是什么
浅拷贝:只是拷贝了对象的实例,但是对象中的属性还是会指向原有的对象。
深拷贝:在浅拷贝的基础上,再将对象中的属性额外的复制一份,对象中的属性会指向新的对象。
如果只是实现基本类型的赋值,只需要实现Cloneable接口即可,但是如果是引用类型的话就需要将这些对象都实现Cloneable接口并重写clone方法。
步骤:
Address类实现Cloneable接口,并重写clone方法
在Person类中重写clone方法
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Address address = ((Person) obj).getAddress();
((Person) obj).setAddress((Address) address.clone());
return obj;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}测试
@Test
public void testShallowClone() throws CloneNotSupportedException {
Address address = new Address();
address.setType("home");
address.setName("北京");
Person p1 = new Person();
p1.setName("tom");
p1.setAge(21);
p1.setAddress(address);
Person p2 = (Person) p1.clone();
p2.getAddress().setType("office");
System.out.println(p1); //Person{name='tom', age=21, address=Address{type='home', name='北京'}}
System.out.println(p2); //Person{name='tom', age=21, address=Address{type='office', name='北京'}}
System.out.println(p1 == p2); //false
}
这样便解决了clone引用类型的问题