<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    即使世界明天毀滅,我也要在今天種下我的葡萄樹。
    posts - 112, comments - 14, trackbacks - 0, articles - 11

    深入 JAVA對象的復制與比較

    Posted on 2007-01-10 10:46 閱讀(207) 評論(0)  編輯  收藏 所屬分類: Java
    1.對象的復制
    ???
    String str1 = "This is a string!"? //這里是 "對象引用" 的復制
    String str2 = new String(str1);? //這里是 "對象實例" 的復制

    淺復制: 只復制復合對象本身.
    深復制: 除了復制復合對象本身, 還復制了復合對象的引用的對象實例.

    例如:

    class Pupil{
    ??? public Pupil(String sno, String name, int age){
    ??????? this.sno = new String(sno);
    ??????? this.name = new String(name);
    ??????? this.age = age;
    ??? }

    ??? public String getSno() {
    ??????? return sno;
    ??? }

    ??? public String getName() {
    ??????? return name;
    ??? }

    ??? public int getAge() {
    ??????? return age;
    ??? }

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

    ??? private String sno;
    ??? private String name;
    ??? private int age;
    }

    public class CopyDemo {
    ??? public static Pupil[] shallowCopy(Pupil[] aClass) {
    ??????? Pupil[] newClass = new Pupil[aClass.length];

    ??????? //此時newClass 與aClass 指向同一塊內存
    ??????? for(int i=0; i<aClass.length; i++)
    ??????????? newClass[i] = aClass[i];
    ??????? return newClass;
    ??? }
    ????
    ??? public static Pupil[] deepCopy(Pupil[] aClass) {
    ??????? Pupil[] newClass = new Pupil[aClass.length];

    ??????? //此時newClass 與aClass 的相應sno , name 指向同一塊內存
    ??????? for(int i=0; i<aClass.length; i++) {
    ??????????? String sno = aClass[i].getSno();
    ??????????? String name = aClass[i].getName();
    ??????????? int age = aClass[i].getAge();
    ??????????? newClass[i] = new Pupil(sno, name, age);
    ??????? }

    ??????? return newClass;
    ??? }

    ??? public static Pupil[] deeperCopy(Pupil[] aClass) {
    ??????? Pupil[] newClass = new Pupil[aClass.length];

    ??????? //完全的復制
    ??????? for(int i=0; i<aClass.length; i++) {
    ??????????? String sno = new String(aClass[i].getSno());
    ??????????? String name = new String(aClass[i].getName());
    ??????????? int age = aClass[i].getAge();
    ??????????? newClass[i] = new Pupil(sno, name, age);
    ??????? }

    ??????? return newClass;
    ??? }
    }

    2.clone()的使用

    * Object.clone()
    * Cloneable 接口
    * CloneNotSupportedException

    a. 使用Object.clone 進行復制
    兩個必須條件:
    1.一定要將重定義后的clone() 方法定義為公有方法(在Object 類中, 它是受保護的成員,??? 不能直接使用)
    2.該后代類聲明實現接口 Cloneable 接口(當類實現該接口, 其任何子類也會繼承該接口), 該接口實際上沒有任何
    ? 內容, 只是一個標識, 標志實現該接口的類提供clone() 方法.(這是接口的一種非典型用法)

    public class Fraction implements Cloneable {
    ??? public Object clone() {
    ??????? try{
    ??????????? return super.clone();? //call protected method
    ??????? } catch (CloneNotSupportedException e) {
    ??????????? return null;
    ??????? }
    ??? }
    ??? //other methods ...
    }


    b.重寫Object.clone()
    例如對?? private char[] cb; character buffer 進行復制
    ?
    // add in class Cirbuf
    ??????? public Object clone() {
    ??????? try{
    ??????????? Cirbuf copy = (Cirbuf)super.clone();
    ??????????? copy.cb = (char[])cb.clone();
    ??????????? return copy;
    ??????? }catch (CloneNotSupportedException e){
    ??????????? throw new InternalError(e.toString());
    ??????? }
    ??? }

    c.復制數組
    ? 數組是在方法調用重以引用的形式傳遞的對象. 下述情況下非常適合引用來傳遞數組:
    ? *正在接收的方法不修改數組
    ? *正在調用的方法不必關心是否修改數組
    ? *正在調用的方法想要得到數組中的修改結果
    ? 否則, 就應該在方法調用中傳遞數組對象的副本. 只需調用 arrObj.clone() 方法即可完成數組arrObj 的復制操作. 隨后將該數組副本強制轉換為其正確類型:
    ????? (type[])arrObj.clone();
    ?? System.arraycopy 方法提供一種用于在數組間復制多個元素的有效方式.
    ??????? System.arraycopy(source, i, target, j, len)

    3.對象實例的比較

    例如:

    ??? Pupil p1 = new Pupil("99184001", "zhang3", 18);
    ??? Pupil p2 = new Pupil("99184001", "zhang3", 18);

    a. "=="
    ?? if(p1 == p2)...
    ? 此次測試的是對象引用, 其結果肯定是false, 只要兩個對象引用不是互為別名就不會相等.
    b. 淺比較? false

    ?? if(p1.getSno() == p2.getSno() && p1.getName() == p2.getName()
    ???? && p1.getAge() == p2.getAge()) ...;

    c. 深比較?? true[/code]??
    ? if(p1.getSno().equals(p2.getSno()) && p1.getName().equals(p2.getName())
    ???? && p1.getAge() == p2.getAge()) ...;[/code]
    ??? JAVA API 的跟類Object 也提供了equals() 方法, 但它只是比較兩個對象引用, 而非比較兩個對象實例.
    ??? 不管怎樣, 如果需要比較Pupil 類的對象(例如要將它們放入對象容器), 應該為Pupil 類重定義equals() 方法:
    ???
    ??? public boolean equals(Object otherobj) {
    ??????? //檢查otherobj 是否為空
    ??????? if(otherobj == null) return false;

    ??????? //檢查otherobj 是否就是當前對象
    ??????? if(otherobj == this) return true;

    ??????? //檢查otherobj 是否具有正確的類型, 即檢查是否可與當前對象比較
    ??????? if(!(otherobj instanceof Pupil)) return false;

    ??????? //將otherobj 轉換為Pupil 類的對象引用
    ??????? Pupil tmpObj = (Pupil)otherobj;
    ??????? //關于學生是否相等的邏輯檢查
    ??????? if(sno.equals(tmpObj.sno) && name.equals(tmpObj.name)
    ???????????? && age == tmpObj.age) return true;
    ????????
    ??????? return false;
    ??? }

    ?? JAVA API 所提供的每個類幾乎都提供了采用深比較策略的equals() 方法, 例如String 類equals() 方法. 一般來說, 用戶自己定義的類也應當提供合適的equals() 方法, 特別是當程序要將其對象放入JAVA API 所提供的對象容器類的時候.?
    ?? 按照約定, 任何類所提供的equals() 方法所實現的相等比較應該是等價關系, 即滿足自反性, 對稱性和傳遞性. 另外一個類重定義了equals() 方法, 也應該重定義相應hashCode() 方法, 否則將這個類的對象放入映射對象容器時也會發生以外.

    主站蜘蛛池模板: 免费一级成人毛片| 国产在线观看免费完整版中文版| 亚洲?v女人的天堂在线观看| 亚洲丰满熟女一区二区哦| 最近中文字幕mv免费高清电影| 亚洲熟妇AV一区二区三区浪潮| 日韩a在线观看免费观看| 成人亚洲国产精品久久| 免费a级黄色毛片| 久久精品成人免费观看97| 精品国产亚洲一区二区三区| 日本免费A级毛一片| 亚洲资源在线视频| 黄色片在线免费观看| 久久无码av亚洲精品色午夜| 亚洲午夜精品一级在线播放放 | 国产亚洲A∨片在线观看| 国产精品网站在线观看免费传媒| 日韩va亚洲va欧洲va国产| 无码av免费一区二区三区试看| 亚洲av福利无码无一区二区| 一级毛片免费观看| 亚洲一线产区二线产区区| 免费一区二区视频| 成全视频高清免费观看电视剧| 亚洲高清资源在线观看| 国产成人精品免费直播| 中国一级全黄的免费观看| 久久久亚洲欧洲日产国码是AV| 成人免费男女视频网站慢动作| 一级做a爰全过程免费视频毛片 | 久久久久国产成人精品亚洲午夜 | 蜜桃视频在线观看免费网址入口| 妇女自拍偷自拍亚洲精品| 亚洲欧洲成人精品香蕉网| 国产va免费精品观看精品| 特黄特色大片免费| 精品亚洲麻豆1区2区3区| 国产精品麻豆免费版| 无码精品一区二区三区免费视频| 久久综合久久综合亚洲|