关于java中克隆的学习(一)

    java中的克隆,就是要复制对象,但为什么要用克隆呢?我们直接把对象赋值给其它同类型的实例不就行了吗?这就要从java的值传递和引用传递说起了。

package dcr.study.test.pointer;

public class Obj {
	String str = "init value";

	public String toString() {
		return str;
	}
	
}

 测试值传递和引用传递的代码如下:(注:注释中说明了代码的作用)

package dcr.study.test.pointer;

import java.util.Enumeration;
import java.util.Hashtable;

/*
 * 
 * */
public class ObjRef {
	Obj aObj = new Obj();
	int aInt = 11;

	public void changeObj(Obj inObj) {
		inObj.str = "changed value";
	}

	public void changePri(int inInt) {
		inInt = 22;
	}

	public static void main(String[] args) {
		ObjRef oRef = new ObjRef();

		System.out.println("Before call changeObj() method: " + oRef.aObj);
		oRef.changeObj(oRef.aObj);
		System.out.println("After call changeObj() method: " + oRef.aObj);

		System.out.println("==================Print Primtive=================");

		System.out.println("Before call changePri() method: " + oRef.aInt);
		oRef.changePri(oRef.aInt);
		System.out.println("After call changePri() method: " + oRef.aInt);
		/*
		 * 运行结果如下 Before call changeObj() method: init value After call changeObj()
		 * method: changed value ==================Print Primtive=================
		 * Before call changePri() method: 11 After call changePri() method: 11
		 * 
		 * 方法changeObj(Obj inObj);和方法changePri(int inInt);都是去改变传入的参数值,
		 * 不同的是changeObj(Obj inObj);方法传过的是一个对象,而changePri(int inInt);
		 * 方法传入的却是java的基本类型int,虽然两个方法做了类似的事,但是结果却不一样,传对象
		 * 的方法值被改掉了,但是传java基本类型的方法,值还是原来的值。
		 * 原因是java参数的传递分为两种,值传递和引用传递(不光是java其它语言也一样)。 
		 * 值传递:在java中以 基本类型 和 基本类型的包装类
		 * 做为参数时,都是值传递。 引用传递:以对象做为参数时为引用传递。
		 * 
		 */
		
		System.out.println("==================引用传递=================");
		// 除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递"

		ObjRef oRefA = new ObjRef();
		ObjRef oRefB = oRefA;
		oRefA.aObj.str = "改变oRefA的Obj实例的值";
		System.out.println("Print objB.str value: " + oRefB.aObj.str);

		// 此处我们只改变了oRefA 的 Obj实例的str的值,但是oRefB的Obj实例的str的值同时也变了。
		// 说明了在使用 “=” 号向对象变量赋值的时候,也是使用了“引用传递“。

		System.out.println("=============引用传递导致的麻烦=============");
		// 下面是关于HashTable的一个例子,HashTable真的能存储对象吗?
		Hashtable ht = new Hashtable();
		StringBuilder sb = new StringBuilder();

		sb.append("abc");
		ht.put(1, sb);
		sb.append("def");
		ht.put(2, sb);
		sb.append("ghi");
		ht.put(3, sb);
		sb.append("xyz");
		ht.put(4, sb);
		
		int numObj = 0;
		Enumeration it = ht.elements();
		while (it.hasMoreElements()) {
			System.out.print("get StringBufffer " + (++numObj)
					+ " from Hashtable: ");
			System.out.println(it.nextElement());
		}
		/*
		运行结果如下:
		=============引用传递导致的麻烦=============
		get StringBufffer 1 from Hashtable: abcdefghixyz
		get StringBufffer 2 from Hashtable: abcdefghixyz
		get StringBufffer 3 from Hashtable: abcdefghixyz
		get StringBufffer 4 from Hashtable: abcdefghixyz
		而不是我们期望的
		=============引用传递导致的麻烦=============
		get StringBufffer 1 from Hashtable: abcdefghixyz
		get StringBufffer 2 from Hashtable: abcdefghi
		get StringBufffer 3 from Hashtable: abcdef
		get StringBufffer 4 from Hashtable: abc		
		原因就是引用的传递
		如果在向Hashtable put的时候在 sb的后面加上toString()方法,则可以得到
		我们想要的结果。如:ht.put(1,sb.toString());因为java中基本类型和
		基本类型的包装类都是值传递。
		*/
	}
	
}

 

你可能感兴趣的:(java)