六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

詳述:JAVA不妨克隆

[摘要]經常聽到有人說java中沒有指針。事實如此嗎?no,java是有指針的,只不過換了個名字而已,也就是我們經常提到的引用。我們知道,在java中一切都是對象,那么我們如何操控對象?如何在成千上萬的對象中找到我們所需的那個對象呢?又是如何讓對象按照我們的意思來完成任務的呢?   Object o = ...
經常聽到有人說java中沒有指針。事實如此嗎?no,java是有指針的,只不過換了個名字而已,也就是我們經常提到的引用。我們知道,在java中一切都是對象,那么我們如何操控對象?如何在成千上萬的對象中找到我們所需的那個對象呢?又是如何讓對象按照我們的意思來完成任務的呢?

  Object o = new Object();
  這是java中最常見的語句了,在這句話中做了三件事。首先聲明一個Object類型的變量o,在內存中為對象劃分一塊地址new Object(),將聲明的變量指向內存中的對象。如此一來,我們就可以通過o來操縱對象了。就好像孩子們玩的遙控飛機,在空中飛行的是飛機,而使它做出優美動作的卻是孩子們手中的搖控器。

  "克隆"是如今聽到的較多的詞匯,聽說已經將某只羊克隆了好幾份了。但愿這種技術不要在人身上實驗。java中也有"克隆",與現實世界的克隆一樣,將一個實際存在的對象拷貝幾份。如下:
  //倒霉的羊
  public class Sheep implements Cloneable{
  private String name;
  public void setName(String arg) {
  name = arg;
  }
  public String getName() {
  return name;
  }
  public Object clone() throws CloneNotSupportedException {
  return super.clone();
  }
  }
  //克隆
  public class Main {
  public static void main(String[] args) throws CloneNotSupportedException {
  Sheep sheep = new Sheep(); //先得到那只羊的實例
  sheep.setName("我是真的"); //給它做個記號
  System.out.println("sheep.getName() = " + sheep.getName());
  Sheep sheepClone = (Sheep)sheep.clone(); //開始克隆
  System.out.println("sheepClone.getName() = " + sheepClone.getName());
  }
  }

  運行程序結果為:
  sheep.getName() = 我是真的
  sheepClone.getName() = 我是真的

  兩只羊是一模一樣的(哪怕那只羊瘸腿)。讓我們來看看代碼。首先要注意的是Sheep類實現了Cloneable接口(該接口屬于java.lang包,默認已經導入了),該接口中并沒有定義要實現的方法,是個空接口,起標志作用。也就是說,實現了這個接口的羊就不再是只普通的羊,它是一只可以被克隆的羊。再往下看,有個clone方法,返回Object類型的對象,并拋出CloneNotSupportedException異常。

  該方法覆寫了父類(Object)的clone方法,并在最后調用了super.clone(),這也意味著無論clone類繼承結構是什么樣的,super.clone()都會直接或間接調用Object類的clone()方法。看看jdk幫助文檔會發現,Object類的clone()是一個native方法,我們知道,native方法的效率一般來說都是遠高于java中的非native方法。這也說明了new一個對象,然后將原對象中的數據導入到新創建的對象中去的做法是多么愚蠢。必須說明的是Object中的clone方法是protected的,所以要使用clone就必須繼承Object類(默認)。并且為了可以使其它類調用該方法,必須將其作用域設置為public。

  以上只是一個簡單clone的實現。下面說說"影子clone"和"深度clone"。

  何為影子clone?先看一下例子。
  //倒霉的羊
  public class Sheep implements Cloneable{
  private String name;
  public void setName(String arg) {
  name = arg;
  }
  public String getName() {
  return name;
  }
  public Object clone() throws CloneNotSupportedException {
  return super.clone();
  }
  }
  //羊圈
  public class Sheepfold implements Cloneable {
  public Sheep sheep;
  public String name;
  public Sheepfold() {
  sheep = new Sheep();
  }
  public Object clone() throws CloneNotSupportedException {
  return super.clone();
  }
  }
  //克隆
  public class Main {
  public static void main(String[] args) throws Exception {
  Sheepfold fold = new Sheepfold();
  fold.name = "小羊圈";
  fold.sheep.setName("小羊");
  Sheepfold fold2 = (Sheepfold)fold.clone();
  System.out.println(" fold2.name = " + fold2.name);
  System.out.println(" fold2.sheep.getName() = " + fold2.sheep.getName());
  fold2.name = "大羊圈";
  fold2.sheep.setName("大羊");
  System.out.println("=====================================");
  System.out.println(" fold2.name = " + fold2.name);
  System.out.println("* fold2.sheep.getName() = " + fold2.sheep.getName());
  System.out.println(" fold.name = " + fold.name);
  System.out.println("* fold.sheep.getName() = " + fold.sheep.getName());
  System.out.println("=====================================");
  }
  }

  在這個例子中有三個類,Sheep和Sheepflod都實現了Cloneable接口,并且覆寫了Object類的clone方法,說明這兩個類是具有克隆能力的。注意一點,在Sheepflod中持有一個Sheep的實例,并在Main類中對其進行克隆,結果如下:
  fold2.name = 小羊圈
  fold2.sheep.getName() = 小羊
  =======================
  fold2.name = 大羊圈
  * fold2.sheep.getName() = 大羊
  fold.name = 小羊圈
  * fold.sheep.getName() = 大羊
  ======================

  請注意一下結果中帶有"*"號的兩條結果語句。fold2.sheep和fold.sheep的name都變為了"大羊",很奇怪是嗎?在此之前,我們只對fold2.sheep的name賦過值。為什么fold.sheep的name也變為了"大羊"呢?原因很簡單,因為它們是指向同一個對象的不同引用。從中可以看出,調用Object類中clone()方法時,首先在內存中劃分一塊同原對象相同的空間,然后將原對象的內容原樣拷貝至新對象。

  我們知道,java中有基本數據類型,對于基本數據類型,這樣的操作是沒有問題的,但對非基本類型變量,它們保存的僅僅是對象的引用,這也是為什么clone后非基本類型變量和原對象中的變量指向同一個對象的原因。可能你已經注意到,程序中用到了String類型,即對象,為什么沒有出現引用指向同一地址的情況?

  這是因為String是一個不可更改的類(immutable class),每次給它賦值時,都會產生一個新的String對象。如String str = "a"; str += "b";在這兩句代碼中,當執行str += "b"時,實際上是重新成生了一個值為"ab"的String對象,即重新分配了一塊內存空間。以上clone方法通常被稱為"影子clone"。"影子clone"給我們留下了一個問題,即多個引用指向同一個對象。如何解決該問題呢?答案為"深度clone"。把上面的例子改成深度clone很簡單,只需將Sheepfold的clone()方法改為如下即可:
  public Object clone() throws CloneNotSupportedException {
  Sheepfold fold = (Sheepfold)super.clone();
  sheep = (Sheep)fold.sheep.clone();
  return fold;
  }

  至此,clone就基本完成了。當然,在實際使用過程中需要注意一些問題,比如StringBuffer不可以直接clone(當然,也有解決辦法)等等。

  全文完!




主站蜘蛛池模板: 天堂在线视频网站 | 日韩高清不卡在线 | 亚洲一区二区三区在线 | 在线免费看污视频 | 午夜资源在线 | 日本视频一区二区免费播放 | 一级人做人爰a全过程免费视频 | 日韩在线精品视频 | 亚洲第一视频网站 | 在线播放亚洲精品富二代91 | 日韩欧美网站 | 日韩精品手机在线 | 亚洲福利秒拍一区二区 | 亚洲综合狠狠 | 天堂√在线官网 | 色色网视频 | 婷婷激情狠狠综合五月 | 日本啊v在线观看 | 欧美在线高清视频 | 亚洲欧美日韩高清一区二区一 | 欧美整片在线 | 在线观看aaa | 亚洲热播 | 日本剧情片大全免费的视频 | 亚洲综合第一 | 欲色影视 | 亚洲 欧美 中文字幕 | 中国一级做a爰片久久毛片 中国性欧美 | 视频在线精品 | 青草视频网站 | 日本综合在线 | 日韩中文字幕在线不卡 | 日本福利视频 | 亚洲综合小说网 | 青青草国产精品人人爱99 | 天天爱天天做色综合 | 天天干夜夜拍 | 天天草天天 | 欧美污视频网站 | 中文字幕在线乱码免费毛片 | 情不自禁完整版在线观看免费 |