Java中对象的直接赋值、浅拷贝及深拷贝的理解和应用场景及其实现方式

1.为什么有拷贝?

     因为new一个对象太占用资源,当要复制大量对象的时候用拷贝实现的方式很有优势,很快。

2.浅拷贝与深拷贝

    浅拷贝是指对一个类进行拷贝是,会对基本数据类型进行值传递(string也是基本类型),而对于类属性中对象类型变量(包括数组)会让他们直接指向同一个内存地址,所以修改其中一个的值会影响到拷贝对象中的值,所以具有局限性

    深拷贝基本数据类型拷贝同浅拷贝一样,引用类型变量会直接拷贝,而不是让他们指向同一地址。

具体实现方式:1.通过Object中的clone方法; 2.自己通过构造函数方式实现;3.序列化方法实现

直接赋值

直接赋值是我们最常用的方式,在我们代码中的体现是Persona = new Person();Person b = a,是一种简单明了的方式,但是它只是拷贝了对象引用地址而已,并没有在内存中生成新的对象,我们可以通过下面这个例子来证明这一点


/** 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.tompai.clone;

/**
* @desc: demo
* @name: SimplePerson.java
* @author: tompai
* @email:liinux@qq.com
* @createTime: 2020年1月3日 下午1:21:28
* @history:
* @version: v1.0
*/

public class SimplePerson {

	// 姓名
    private String name;
    // 年龄
    private int age;
    // 邮件
    private String email;
    // 房屋描述
    private String houseDesc;
    
	public SimplePerson(String name, int age, String email, String houseDesc) {
		super();
		this.name = name;
		this.age = age;
		this.email = email;
		this.houseDesc = houseDesc;
	}
	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;
	}
	public String getEmail() {
	
		return email;
	}
	public void setEmail(String email) {
	
		this.email = email;
	}
	public String getHouseDesc() {
	
		return houseDesc;
	}
	public void setHouseDesc(String houseDesc) {
	
		this.houseDesc = houseDesc;
	}
	@Override
	public String toString() {
		return "{\"name\":\"" + name + "\", \"age\":\"" + age + "\", \"email\":\"" + email + "\", \"houseDesc\":\""
				+ houseDesc + "\"}";
	}
}

测试:

// 初始化一个对象
		SimplePerson tompai = new SimplePerson("tompai", 20, "liinux@qq.com", "i am tompai.");
		// 直接赋值
		SimplePerson tompai1 = tompai;
		// 改变 person1 的属性值
		tompai1.setName("not tompai");
		System.out.println("person对象:" + tompai);
		System.out.println("person直接赋值对象:" + tompai1);

我们将 person 对象复制给了 person1 对象,我们对 person1 对象的 name 属性进行了修改,并未修改 person 对象的name 属性值,但是我们最后发现 person 对象的 name 属性也发生了变化,其实不止这一个值,对于其他值也是一样的,所以这结果证明了我们上面的结论:直接赋值的方式没有生产新的对象,只是生新增了一个对象引用,直接赋值在 Java 内存中的模型大概是这样的

浅拷贝
浅拷贝也可以实现对象克隆,从这名字你或许可以知道,这种拷贝一定存在某种缺陷,是的,它就是存在一定的缺陷,先来看看浅拷贝的定义:如果原型对象的成员变量是值类型,将复制一份给克隆对象,也就是说在堆中拥有独立的空间;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。换句话说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。 可能你没太理解这段话,那么我们在来看看浅拷贝的通用模型:

 


/** 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the A
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值