瘋狂java07--物件導向的陷阱
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,呼叫普通方法會報空指標異常,但是呼叫靜態方法不會報錯。底層會轉為類去呼叫方法,同時也不存在父類引用指向子類物件的情形。靜態內部類不能訪問外部類的非靜態成員,可以訪問靜態成員。
相關文章
- 【Java】瘋狂Java基礎(一)——物件導向的特徵:繼承、封裝和多型Java物件特徵繼承封裝多型
- 物件導向-物件導向思想物件
- 物件導向與程式導向物件
- 程式導向與物件導向物件
- “程序導向”和“物件導向”物件
- 物件導向物件
- java的物件導向Java物件
- php中的程式導向與物件導向PHP物件
- 物件導向,搞定物件物件
- JAVA物件導向基礎--物件導向介紹Java物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- 瘋狂的沙王
- 更多物件導向的JavaScript物件JavaScript
- Golang 中的物件導向Golang物件
- JavaScript 的物件導向(OO)JavaScript物件
- Java:Java的物件導向Java物件
- PHP物件導向PHP物件
- 物件導向 -- 反射物件反射
- JavaScript 物件導向JavaScript物件
- JS物件導向JS物件
- Java物件導向Java物件
- Python——物件導向Python物件
- 物件導向--下物件
- scala物件導向物件
- 物件導向(下)物件
- Python物件導向Python物件
- 物件導向(oop)物件OOP
- [Java物件導向]Java物件
- python 物件導向Python物件
- Java — 物件導向Java物件
- 物件導向(上)物件
- python-程式導向、物件導向、類Python物件
- JavaScript物件導向—物件的建立和操作JavaScript物件
- Java物件導向——類與物件Java物件
- Js物件導向(1): 理解物件JS物件
- 解釋下什麼是物件導向?物件導向和麵向過程的區別?物件
- 物件導向 -- 類的組合物件
- GO 語言中的物件導向Go物件