當前位置:首頁 » 編程語言 » java深克隆

java深克隆

發布時間: 2022-12-21 13:39:18

java中的克隆技術具體有什麼應用

Clone基本知識儲備
在Java里提到clone技術,就不能不提java.lang.Cloneable介面和含有clone方法的Object類。所有具有clone功能的類都有一個特性,那就是它直接或間接地實現了Cloneable介面。否則,我們在嘗試調用clone()方法時,將會觸發CloneNotSupportedException異常。 下面我們通過對Object類的部分源碼的分析,來發現和理解這一特性。
l clone的實現

1.實現Cloneable介面

通過上一篇的介紹,我們知道,一個類若要具備clone功能,就必須實現Cloneable介面。做到這一步,clone功能已經基本實現了。Clone功能對我們來說,最主要的還是要能夠使用它。那麼我們如何才能使用clone功能呢?答案是覆蓋Object#clone()方法。

2. 覆蓋Object#clone()方法

為什麼需要覆蓋Object#clone()方法?這里得再次從jdk源碼說起。JDK中Object# clone()方法的原型是:

protected native Object clone() throws CloneNotSupportedException;

是否注意到,這里clone()方法修飾符是protected,而不是public。這種訪問的不可見性使得我們對Object#clone()方法不可見。相信讀者已明白為什麼要覆蓋Object#clone()方法。而且,覆蓋的方法的修飾符必須是public,如果還保留為protected,覆蓋將變得沒有實際意義。下面舉一個具有clone功能的簡單的例子:

/*

* 具有clone功能的類的例子

*/

public class CloneableObjExample implements Cloneable {

//……部分代碼已省略……

private String name = null;

private int score = 0;

/**

* NOTE: 將protected 修飾符 更改為 public

* @see java.lang.Object#clone()

*/

public/*protected*/ Object clone() throws CloneNotSupportedException {

// call父類的clone方法

Object result = super.clone();

//TODO: 定製clone數據

return result;

}

}

3.定製clone

至此,clone已經真相大白。Clone的對象我們可以對其進行定製。還就上面的例子來說。下面的方法對功能做了一定的增強:

public/*protected*/ Object clone() throws CloneNotSupportedException {

// call父類的clone方法

CloneableObjExample result = (CloneableObjExample)super.clone();

//TODO: 定製clone數據

//雖然」clone」了,但還可以做點調整

result.name = 「New Name」;

result.score = 90;

return result;

}

本篇介紹了如何實現clone。接下來的篇幅將就縱深clone等clone的高級特性進行分析。

本章將進入clone的高級特性,著重講述縱深clone技術。

Clone通常有兩種類型即淺clone和深clone。首先,分析一下兩種的不同。淺clone和深clone都是clone,它們本質區別是對象內部的成員屬性(非原生類型屬性,如int等)在clone時是否處理為引用。如果仍然保留為引用,則稱為淺clone,反之稱為深clone。其實這兩個概念也是相對的概念。在處理上它們有點區別,淺clone方式得到clone對象即可,深clone方式在得到clone對象後,還需要對引用的成員屬性進行「clone」處理。從這個層次上說,深clone並沒有什麼特別地困難,簡單講就是創建好對象,再設置一些成員屬性。關於深clone,網上的文章已經有太多,有點目不暇接的感覺,本文不再贅述,這也不是本文的重點。

本文的重點是要闡述縱深clone,亦即「N深clone」。深到什麼程度為止?本文描述的目標是一直深到你想要的程度,包括深到不能再深的程度。

㈡ java怎麼樣構造函數復制一個對象

一、用Object 本身的復制對象的方法, clone()。對象可克隆的類必須實現Cloneable介面,並且clone方法是淺克隆。
二、類實現Serializable,用ObjectOutputStream、ObjectInputStream 來復制對象。

對象克隆有點復雜,尤其是第一種。
關於這個問題你可以搜索:
JAVA深復制(深克隆)與淺復制(淺克隆)
這篇文章看看。

㈢ java中深克隆與淺克隆的區別

深克隆與淺克隆

大家知道,對象是互相引用的,即對象中可能包含了另一個對象的引用,舉例如:有一個Order對象,Order對象中又包含了LineItems對象,然後LineItems對象又包含了Item對象。

好了,現在我有一個Order對象order1,它包含了一個LineItems對象items,這表示的是有一個訂單order1,訂單的內容是items。

好的,現在有另一個客戶想要一份訂單,內容跟order1完全一樣,那麼在系統的邏輯層我們怎麼做呢?很簡單,order2=order1.clone(). 我們知道clone方法是在內存中生成一個新的對象,而不是只得到原對象的引用。這時候,有人說話了:「哦,明白了我們對order2的成員變數進行修改,是不會影響order1的。」 很可惜,這句話只對了一半。

假設order類有一個成員變數name,當然改變order2.name不會影響order1.name,因為他們在不同的內存區域。但是如果改變 order1.items呢?很遺憾,簡單地使用order1.clone,是會影響到order2.items的。原因很簡單,就是因為clone方法默認的是淺克隆,即不會克隆對象引用的對象,而只是簡單地復制這個引用。所以在上例中,items對象在內存中只有一個,order1和order2都指向它,任何一個對象對它的修改都會影響另一個對象。

那相對淺克隆,深克隆自然就是會克隆對象引用的對象了。也就是說,在上例中,改變order1.items並不會影響order2.items了。因為內存中有兩個一樣的items。

如果實現深克隆?

一個方法自然是重寫clone方法,添加如order.items=(LineItems)items.clone()的語句,也就是人為地添加對引用對象的復制。這個方法的缺點是如果引用對象有很多,或者說引用套引用很多重,那麼太麻煩了。業界常用的方法是使用串列化然後反串列化的方法來實現深克隆。由於串列化後,對象寫到流中,所有引用的對象都包含進來了,所以反串列化後,對等於生成了一個完全克隆的對象。絕!

這個方法的要求是對象(包括被引用對象)必須事先了Serializable介面,否則就要用transient關鍵字將其排除在復制過程中。

㈣ java.util.ArrayList.clone是不是徹底的克隆

你好,官方api 說明如下:

Returns a shallow of this ArrayList instance. (The elements themselves are not copied.)
arraylist.clone是淺拷貝,淺拷貝是指拷貝對象時僅僅拷貝對象本身(包括對象中的基本變數),而不拷貝對象包含的引用指向的對象。深拷貝不僅拷貝對象本身,而且拷貝對象包含的引用指向的所有對象。

㈤ java中的淺克隆和深克隆是什麼

淺克隆:僅僅復制所克隆的對象,而不復制它所引用的對象。

被復制對象的所有變數都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。


深克隆:把要復制的對象所引用的對象都復制了一遍。

那些引用其他對象的變數將指向被復制過的新對象,而不再是原有的那些被引用的對象。


很明顯二者時間消耗有差距,在不影響的情況下盡量用淺克隆

注意區分與C語言的淺克隆深克隆 那個是引用地址與重新分配地址構建的區別,詳細可以參見:

http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html

㈥ java深拷貝對象與新建對象哪個更耗資源

這個問題沒有可比性:
首先淺克隆比new性能高
而深克隆包括克隆對象本身以及對象內部的所有成員, 以及成員的成員等,
如果這個對象有一個集合欄位, 這個欄位里有100w個對象, 那麼深克隆要克隆100w+1個對象, 而你所說的新建對象, 如果是new一個對象, 然後set這個100w的集合, 那麼肯定性能更好, 而你如果是new一個對象, 然後new一個集合, 然後把集合里的100w個對象每個都重新new, 並添加到集合中, 然後賦值到新的對象上, 那麼還是克隆的性能好

㈦ java如何實現將一個記事本文件內容復制到另一個文件

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyMove {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CopyMove cm = new CopyMove();
cm.("h:\\1.txt", "c:\\2.txt");
cm.move("h:\\3.txt", "h:\\r\\e\\4.txt");
}
//文件復制前必須得到當前文件夾名字且要有\
//當復制深層次路徑時要用mkdirs方法
public void (String path1,String path2){
try {
FileInputStream fis = new FileInputStream(path1);
int l = fis.available();
byte[] c = new byte[l];
fis.read(c);
fis.close();
int i = path2.lastIndexOf("\\")+1;
System.out.println(i);
String path = path2.substring(0, i);
System.out.println(path);
File f = new File(path);
f.mkdirs();
// System.out.println(f.getAbsolutePath());
// System.out.println(f.isDirectory());
FileOutputStream fos = new FileOutputStream(path2);
fos.write(c);
fos.close();
System.out.println("文件復製成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("文件復制失敗");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void move(String path1,String path2){
try {
FileInputStream fis = new FileInputStream(path1);
int l = fis.available();
byte[] c = new byte[l];
fis.read(c);
fis.close();
int i = path2.lastIndexOf("\\");
//System.out.println(i);
String path = path2.substring(0, i);
System.out.println(path);
File f = new File(path);
f.mkdirs();
// System.out.println(f.getAbsolutePath());
// System.out.println(f.isDirectory());
FileOutputStream fos = new FileOutputStream(path2);
fos.write(c);
fos.close();
System.out.println("文件移動成功");
File f2 = new File(path1);
f2.delete();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("文件移動失敗");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

㈧ 誰能給出一個java中深拷貝 的例子 啊,我不知道是啥東西,最好能解釋下深拷貝含義.

舉個最簡單的例子:
class A {
public int i;
public int j;
}

A a = new A();

淺拷貝:
A a1 = a;

深拷貝:
A a1 = new A();
a1.i = a.i;
a1.j = a.j;

感覺如下:
淺拷貝只拷貝對象本身
深拷貝則拷貝對象中引用的對象,一直拷貝下去。

㈨ java如何深度一個object

方法一:把對象序列化之後再反序列化,之後得到的對象就是深度克隆的對象;
方法二:自己重寫方法,不過有點麻煩。

㈩ java里clone方法的問題

首先必須實現介面,
public interface Cloneable此類實現了 Cloneable 介面,以指示 Object.clone() 方法可以合法地對該類實例進行按欄位復制。

如果在沒有實現 Cloneable 介面的實例上調用 Object 的 clone 方法,則會導致拋出 CloneNotSupportedException 異常。

按照慣例,實現此介面的類應該使用公共方法重寫 Object.clone(它是受保護的)。請參閱 Object.clone(),以獲得有關重寫此方法的詳細信息。
==》protected Object clone() throws CloneNotSupportedException

注意,此介面不 包含 clone 方法。因此,因為某個對象實現了此介面就克隆它是不可能的。即使 clone 方法是反射性調用的,也無法保證它將獲得成功。

public class Box implements Cloneable{

public Date d = new Date();

@Override
public Box clone() throws CloneNotSupportedException
{
Box cloned = (Box)super.clone();

cloned.d = (Date)d.clone();

return (Box)super.clone();
}
public static void main(String[] args) throws Exception {
Box b = new Box();
Box b2 = (Box)b.clone();

System.out.println(b.d == b2.d);
}
}

測試後直接返回的話結果是地址相等。
你在克隆後用了set方法重新操作了,肯定是不一樣的。。。。!!!
3,注釋起來後結果是改變了的,你會不會是沒編譯保存。
你們老師是說的對的

你好,當然知道 你說的那樣。我正是因為三個的試過了,所以最後沒改回去,那不正是你第二個問題嘛。。。
如果是深克隆就是FALSE 不是深克隆就返回TRUE啊。

熱點內容
湖人雙核配置哪個最好 發布:2025-05-15 10:09:48 瀏覽:979
手機熱點密碼怎麼查看 發布:2025-05-15 09:54:47 瀏覽:108
生意發力雲存儲 發布:2025-05-15 09:54:45 瀏覽:616
編寫一個shell腳本添加用戶 發布:2025-05-15 09:54:43 瀏覽:505
資料庫查看錶命令 發布:2025-05-15 09:52:27 瀏覽:914
p30是不是自帶方舟編譯器 發布:2025-05-15 09:51:48 瀏覽:599
追擊世界房間密碼是多少 發布:2025-05-15 09:51:46 瀏覽:995
cjavabyte 發布:2025-05-15 09:51:36 瀏覽:463
visa存儲卡 發布:2025-05-15 09:35:07 瀏覽:619
js調用php的方法 發布:2025-05-15 09:29:13 瀏覽:496