java中clone方法,Java中clone()方法浅析

一、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引用类型的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值