瘋狂java07--物件導向的陷阱

爪哇島的流浪漢發表於2018-08-07

7.1instance運算子的陷阱

instance運算子前面運算元的編譯時型別必須是如下三種情況:

*與後面的型別相同

*是後面型別的子類                否則無法通過編譯

*是後面型別的父類         

instance運算返回的結果與前一個運算元實際引用的物件的型別有關,如果它實際引用的物件是第二個運算元的例項,或者是第二個運算元的子類,實現類的例項,instance運算的結果返回false,否則返回true。

編譯器編譯java程式時,無法檢查引用變數實際引用物件的型別,只檢查該變數編譯時的型別。

強制轉型

*編譯階段 強制轉型要求被轉型變數的編譯時型別必須是如下三種之一:

與目標型別相同;是目標型別的父類;是目標型別的子類;否則編譯錯誤

*執行階段 被轉型變數所引用物件的實際型別必須是目標型別的例項,或者是目標型別的子類,實現類的例項

否則在執行時將引發ClassCastException異常

一個隱蔽的陷阱:String s=null; s instanceof String------>false它實際並未引用一個真正的String物件。

一個重要的作用:可以保證第一個運算元所引用的物件不是null。不會擔心引發ClassCastException或者NullPointerException。

7.2構造器的陷阱

當為構造器宣告新增任何返回值型別宣告,或者新增void宣告該構造器沒有返回值時,編譯器並不會提示這個構造器有錯誤,只是系統會把這個所謂的構造器當成普通方法處理。

以下面兩種方式建立的java物件無需使用構造器

*使用反序列化的方式恢復java物件,但系統中將會產生兩個物件,破壞單例的規則,除非提供readResolve()方法。

*使用clone方法複製java物件,但系統中將會產生兩個物件。

7.3持有當前類的例項

一個類的例項持有當前類的其它例項時需要特別小心,因為程式很容易形成遞迴呼叫

7.4過載方法的呼叫問題

java虛擬機器在識別方法時具有一定的智慧,它可以對呼叫方法的實參進行向上轉型,使之適合被呼叫方法的需要。

java的過載解析過程分成以下兩個階段:第一階段JVM將會選取所有可獲得並匹配呼叫的方法或者構造器;

第二階段決定到底呼叫哪個方法,此時JVM會在第一階段所選取的方法或者構造器中再次選取最精確匹配的那一個。

在複雜的情況下,JVM無法斷定哪個方法更匹配實際呼叫,程式將會導致編譯錯誤。

7.5方法重寫的陷阱

*父類中定義的private方法不可能被子類重寫

*對於不使用訪問控制修飾符的方法,它只能被當前類處於同一個包中的其它類訪問,其它包中的子類依然無法訪問該方法

7.6非靜態內部類的陷阱

*非靜態內部類inner並沒有無引數的構造器,它的構造器需要一個Outer引數。即使系統為非靜態內部類提供一個預設的構造器,這個預設的構造器也需要一個外部類形參。

public class Outer {
    public static void main(String[] args) throws Exception {
        new Outer().test();
    }
    private void test() throws Exception{
        System.out.println(new Inner());                                    (1)
//      System.out.println(Inner.class.newInstance());              (2)
    }
    
    public class Inner{
        public String toString(){
            return "inner物件";
        }
    }
}

(1)處的程式碼程式表面上呼叫Inner無引數的構造器建立例項,實際上虛擬機器底層會將this(代表當前預設的outer物件)作為

引數傳入Inner構造器。

(2)行程式碼效果則不同,程式通過反射指定呼叫Inner類無引數的構造器,所以引發了執行時異常。

*非靜態內部類不能擁有靜態成員

*非靜態內部類在外部以內派生子類是安全的

*推薦使用靜態內部類,因為對於靜態內部類來說,它的外部類就相當於它的一個包,因此靜態內部類的用法就簡單多了,限制也少多了。

宣告一個物件,賦值為null,呼叫普通方法會報空指標異常,但是呼叫靜態方法不會報錯。底層會轉為類去呼叫方法,同時也不存在父類引用指向子類物件的情形。靜態內部類不能訪問外部類的非靜態成員,可以訪問靜態成員。

 

 

 

相關文章