java之迷—類

來源:互聯網
上載者:User

我沒按照順序讀書的,看什麼感興趣就先讀什麼,呵呵。

  1. 令人混淆的構造器案例,猜測一下,下面的程式列印什嗎?

   public class Confusing {
    private Confusing(Object o) {
        System.out.println("Object");
    }    
    private Confusing(double[] dArray) {
        System.out.println("double array");
    }
    public static void main(String[] args) {
        new Confusing(null);
    }
}
你 可能認為應該隨機調用這兩個重載函數中的某一個,不幸的是你會發現一直重複輸出的是:double array。證明只有第二個函數被調用。為何?這跟java對重載函數的解析有關,JAVA對重載函數的解析分為兩步,首先尋找出所有可獲得的並且可應用 的構造器或者方法,第2步從這些方法中尋找出適合“最精確”的。在本例中,第1個函數能接受的參數範圍大於第二個函數,所以對於null來說,第二個函數 更為“精確”。這就告訴我們一點,在撰寫重載函數時,請確保所有重載版本所接受的參數類型盡量做到不相容!

        2。Null與Void,很有趣的例子:

     public class Null {
    public static void greet() {
        System.out.println("Hello world!");
    }

    public static void main(String[] args) {
        ((Null) null).greet();
    }
}

這個能編譯通過嗎?你可能要問,呵呵,確實可以,列印經典的Hello World。本質上,((Null)null).greet();等價於Null.greet();,因為greet是static method,即類方法,它與具體的對象執行個體無關!雖然你在此指定了運算式null,但此值將被忽略。這樣的寫法容易造成混淆,在調用類方法(靜態方法 時)請盡量使用類名來調用!

       3。此章中有幾個例子詳細討論了類中的變數初始化順序問題。需要避免幾個種情況:

       A。要當心類的初始化順序,特別是在你無法確定的情況下,請編寫適當的測試。

      B。不要在建構函式中調用可能被覆寫的方法。因為這些方法可能在子類中被覆寫,導致不可預知的行為。

      C。對靜態變數的初始化需要特別注意順序,靜態域,甚至是final型的靜態域,都可能在它們被正確地初始化之前被使用。

      4。看看一個程式,動態綁定與靜態繫結。

     class Dog {
    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {
    public static void bark() { }
}

public class Bark {
    public static void main(String args[]) {
        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}

啊,你可能一開始就認為這應該是動態綁定吧,多態性!!那麼應該只列印一個woof吧!可並非如此,可憐的小狗Basenji也叫喚了(據書中所 說,此種狗在非洲,而且從來不叫喚,無法想象這世上有不叫喚的狗,呵呵)。問題就在於bark是一個靜態方法,而靜態方法的調用不存在任何動態綁定機制! 對於靜態方法,只會根據調用者的編譯期類型進行調用,woofer,nipper都被聲明為Dog,他們的編譯期類型相同。你可能要問,子類 Basenji中的bark()方法不是覆寫了父類中的bark方法,那麼是怎麼回事?答案是它隱藏了父類中的bark方法,靜態方法是不能被覆寫的,他 們只能被隱藏。要想使這隻可憐的小狗迴歸不叫喚的“正常”狀態,去掉方法之前的static標籤即可。

     5。instanceof操作符的特點:

     A。null instanceof String時返回false,即左運算元為null時返回false

    B。instantceof在編譯期就會判斷左運算元是否是右運算元的子類型,如果不是,在編譯期就無法通過

    C。編譯期通過了,不意味著左運算元就是右運算元的類型或者子類型了,當你進行轉型操作時將進行運行期判斷,如轉型失敗拋出ClassCastException。

      6。我們經常遇到這樣的需求,跟蹤一個類建立出來的執行個體個數,典型方法是在它的建構函式中遞增一個私人的靜態變數,如:

    public class Creator {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++)
            Creature creature = new Creature();
           
        System.out.println(Creature.numCreated());
    }
}

class Creature {
    private static long numCreated = 0;

    public Creature() {
        numCreated++;
    }

    public static long numCreated() {
        return numCreated;
    }
}

你嘗試著運行此程式,並指望它列印100,可惜,它沒有,因為你連編譯都沒辦法通過。。。。。為什嗎?出錯資訊如下:

E:/book/Java/Javapuzzlers/src/com/denny_blue/puzzlers/classy/Creator.java:18: 不是語句
            Creature creature = new Creature();
E:/book/Java/Javapuzzlers/src/com/denny_blue/puzzlers/classy/Creator.java:18: 需要 ';'
            Creature creature = new Creature();
2 錯誤
很 奇怪是不?其實很簡單, Creature creature = new Creature();這是一句local variable declaration statement,而java語言規範(JLS14.4)是不允許一個本地變數聲明語句作為一條語句在for,while或者do中迴圈執行的,它只能 直接出現在一個語句塊中(block),所以簡單的解決辦法就是給這句話加上{},或者

 for (int i = 0; i < 100; i++)
            new Creature();
編譯通過,。現在也可以正常列印出100了,還有個問題,如果有多線程並行地建立對象,那麼我們需要同步計數器代碼和訪問計數器的代碼:

   class Creature {
    private static long numCreated = 0;

    public Creature() {
        synchronized (Creature.class){
           numCreated++;
        }
    }

    public static  synchronized long numCreated() {
        return numCreated;
    }
}

如果你使用JDK5或者更新的版本,你可以使用新引入的ActiomicLong,這實在是好東西,我對JDK5新引入的這個並發包瞭解太少。它在面臨並發時可以繞過同步需求:

import java.util.concurrent.atomic.AtomicLong;
/**
 *
 * @author dennis
 */
public class Creature {
    private static AtomicLong numCreated=new AtomicLong();
    /** Creates a new instance of Creature */
    public Creature() {
        numCreated.incrementAndGet();
    }
    public static long numCreated(){
        return numCreated;
    }
   
}

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=708983

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.