java中的clone()方法的研究---(9)如何编写正确的clone()方法:Collection

在自定义类Person中,会有Collection集合类型。

下面我就不一步步测试给大家看了,我就直接贴出来正确的clone方法了。

目前针对,ArrayList<String>, ArrayList<Integer>这两个类型。


package tt.vo;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

public class Person implements Cloneable {

	// 基本数据类型
	private int age;

	// Wrapper Class类型
	private Integer height;

	// String 类型
	private String name;

	// StringBuffer
	private StringBuffer address1;

	// StringBuilder
	private StringBuilder address2;

	// Date
	private Date date;

	// Timestamp
	private Timestamp timestamp;

	// int array
	private int[] intArray;

	// Integer Array
	private Integer[] integerArray;

	// String Array
	private String[] stringArray;

	private ArrayList<String> stringList;

	private ArrayList<Integer> integerList;

	@Override
	public Person clone() throws CloneNotSupportedException {
		Person p = (Person) super.clone();

		// StringBuffer,StringBuilder 没有实现clone方法
		// 只能用 new, 去完成克隆动作
		if (this.address1 != null) {
			p.address1 = new StringBuffer(this.address1);
		}

		if (this.address2 != null) {
			p.address2 = new StringBuilder(this.address2);
		}

		if (this.date != null) {
			p.date = (Date) this.date.clone();
		}

		if (this.timestamp != null) {
			p.timestamp = (Timestamp) this.timestamp.clone();
		}

		if (this.intArray != null) {
			p.intArray = this.intArray.clone();
		}

		if (this.integerArray != null) {
			p.integerArray = this.integerArray.clone();
		}

		if (this.stringArray != null) {
			p.stringArray = this.stringArray.clone();
		}

		// list clone 要强转类型, 此处是对list的浅克隆
		if (this.stringList != null) {
			p.stringList = (ArrayList<String>) this.stringList.clone();
		}

		if (this.integerList != null) {
			p.integerList = (ArrayList<Integer>) this.integerList.clone();
		}

		return p;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Integer getHeight() {
		return height;
	}

	public void setHeight(Integer height) {
		this.height = height;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public StringBuffer getAddress1() {
		return address1;
	}

	public void setAddress1(StringBuffer address1) {
		this.address1 = address1;
	}

	public StringBuilder getAddress2() {
		return address2;
	}

	public void setAddress2(StringBuilder address2) {
		this.address2 = address2;
	}

	@Override
	public String toString() {
		return "Person [age=" + age + ", height=" + height + ", name=" + name
				+ ", address1=" + address1 + ", address2=" + address2
				+ ", date=" + date + ", timestamp=" + timestamp + ", intArray="
				+ Arrays.toString(intArray) + ", integerArray="
				+ Arrays.toString(integerArray) + ", stringArray="
				+ Arrays.toString(stringArray) + ", stringList=" + stringList
				+ ", integerList=" + integerList + "]";
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public Timestamp getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(Timestamp timestamp) {
		this.timestamp = timestamp;
	}

	public Integer[] getIntegerArray() {
		return integerArray;
	}

	public void setIntegerArray(Integer[] integerArray) {
		this.integerArray = integerArray;
	}

	public String[] getStringArray() {
		return stringArray;
	}

	public void setStringArray(String[] stringArray) {
		this.stringArray = stringArray;
	}

	public int[] getIntArray() {
		return intArray;
	}

	public void setIntArray(int[] intArray) {
		this.intArray = intArray;
	}

	public ArrayList<String> getStringList() {
		return stringList;
	}

	public void setStringList(ArrayList<String> stringList) {
		this.stringList = stringList;
	}

	public ArrayList<Integer> getIntegerList() {
		return integerList;
	}

	public void setIntegerList(ArrayList<Integer> integerList) {
		this.integerList = integerList;
	}

}

---------------------------------------------------------------下面开始测试了------------------------------------------------------------------

测试类TestMain:


package tt;

import java.util.ArrayList;
import java.util.Arrays;

import tt.vo.Person;

public class TestMain {

	public static void main(String[] args) throws CloneNotSupportedException {
		// initialize Person p
		Person p = new Person();
		
		// String List
		ArrayList<String> stringList = new ArrayList<String>();
		stringList.addAll(Arrays.asList(new String("0"), new String("1")));
		p.setStringList(stringList);
		
		// Integer List
		ArrayList<Integer> integerList = new ArrayList<Integer>();
		integerList.addAll(Arrays.asList(new Integer("0"), new Integer("1")));
		p.setIntegerList(integerList);
		
		System.out.println("p:" + p);
		Person pclone = p.clone();
		System.out.println("pclone:" + pclone);
		
		
		
		
		System.out.println("-------------after set-------------------");
		
		// string list
		String stringItem0 = p.getStringList().get(0);
		stringItem0 = "0000";
		p.getStringList().add("111111");
		
		// integer list
		Integer integerItem0 = p.getIntegerList().get(0) ;
		integerItem0 = 999;
		p.getIntegerList().add(88888);
		
		
		System.out.println("p:" + p);
		System.out.println("pclone:" + pclone);
	}
}


debug截图:



通过debug可以发现:

  • p.integerList = (ArrayList<Integer>) this.integerList.clone();     是浅克隆, 在浅克隆之后:
  • p.integerList(id=25)与 pclone.integerList(id=34) id不同
  • 我们要知道ArrayList内部维护的是Object [] elementData。
  • p.integerList.elementData(id=36)和pclone.integerList.elementData(id=47) id不同
  • 说白了,还是数组的id不同(和我上一篇讲数组克隆情况一样),虽然数组里面的元素的id都相同,
  • 但是在对p.integerList操作的时候(add,remove),是不会影响到pclone.integerList的
  • 也因为是浅克隆:数组里面的元素的id都相同。
  • 注意,这里要结合之前的帖子(Integer,String):
    • 当从list取出Integer,String类型的变量之后,
    • 你修改了stringItem0,integerItem0之后,是不会影响数组里面所对应的元素的。
    • 至于原因?看看http://blog.csdn.net/miqi770/article/details/45223191
  • 对于p.stringList和p.integerList的现象是一样的。


### 回答1: 在 Java ,可以使用以下几种方法获得对象的控制权: 1. synchronized 关键字:可以使用 synchronized 关键字来保证同一时间只有一个线程访问该对象。 2. java.util.concurrent 包的 Lock 接口:可以使用 Lock 接口的 lock() 和 unlock() 方法来获得和释放对象的控制权。 3. wait() 和 notify() / notifyAll() 方法:可以使用 wait() 方法来释放对象的控制权,并使当前线程等待;使用 notify() 或 notifyAll() 方法可以唤醒正在等待该对象的线程。 这些方法通常与 Java 的多线程相关,在不同的场景使用不同的方法来获得对象的控制权,以保证多线程访问对象的正确性。 ### 回答2: 在Java,可以通过以下方法获得对象的控制权: 1. 构造方法(Constructor):在创建对象时,通过调用对象的构造方法可以初始化对象的属性和状态。 2. 类的普通方法(普通方法):可以通过调用对象的普通方法来执行对象的特定操作,并且可以修改对象的属性和状态。 3. 类的静态方法(静态方法):通过调用类的静态方法可以执行一些与对象无关的操作,例如工具类方法,不需要实例化对象即可调用。 4. 访问器方法(Getter):通过定义访问器方法(也称为getter方法)可以获取对象的属性值。 5. 修改器方法(Setter):通过定义修改器方法(也称为setter方法)可以修改对象的属性值。 6. 对象引用(Object Reference):如果将一个对象赋值给另一个对象的引用变量,那么该引用变量将指向同一个对象,可以通过该引用变量来操作对象。 7. 垃圾回收(Garbage Collection):Java的垃圾回收机制会自动回收没有被引用的对象,因此可以通过及时释放对象的引用来放弃对对象的控制权。 需要注意的是,Java的控制权是通过对象引用的方式来控制的,而不是直接控制对象本身。 ### 回答3: 在Java,可以使用以下几种方法获得对象的控制权: 1. 构造方法:在创建类的实例时,通过调用该类的构造方法来初始化对象的状态。构造方法具有特殊的性质,它们在对象创建过程被自动调用,并且只能在创建对象时被调用一次。 2. 静态工厂方法:静态工厂方法是一个静态方法,它返回该类的一个实例。相比于构造方法,它具有更大的灵活性,可以自定义返回的对象实例。通过静态工厂方法,可以实现对象的控制权转移到指定的方法。 3. 克隆方法Clone()是Object类的一个方法,在实现了Cloneable接口的类可以被重写。通过调用克隆方法,可以创建一个与原始对象完全相同的副本对象。克隆方法可以在某些场景下获取对象的控制权。 4. 反射:反射是Java的一种机制,可以在运行时动态地获取对象的信息(类名、属性、方法等),并对其进行操作。通过反射,可以实现获取对象的控制权,例如创建对象、调用方法等。 总的来说,以上是一些常用的方法来获得Java对象的控制权。不同方法有着各自的特点和应用场景,开发者可以根据实际情况选择适合的方法来获取对象的控制权。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值