instanceof :
1)、類與類: 判斷繼承鏈上的執行個體,一般使用在強轉之前的判斷(多態應用時,即多態作為形參時)
2)、介面與類:介面可插拔,類都可以instanceof編譯
編譯看類型,運行找對象,不能通過編譯
注意:final 類 不可能發生多態
已經確定的類體,指匿名子類對象
3)、介面與介面 :存在繼承關係
不存在編譯問題:主要看可能存在多態
代碼體現:
1)String類重寫Object類的equals方法(方法簽名必須一致)
public boolean equals(Object anObject){ //形參是多態時,才可以使用instanceof判斷,因為多態存在於繼承體系中 if(this==anObject) //對象地址值相同直接返回真. return ture; if(anObject instanceof String){ //判斷傳入的實參是否為String類型,因為形參類型是固定的(重寫的要求),所以需要判斷 String anotherString = (String)anObject; //強制轉換 int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } return false;}
2)除final修飾的類及匿名子類對象外,幾乎所有的類都可以通過instanceof + 介面編譯(因為可能存在多態)
能否編譯通過,遵循一個原則:是否可能與介面發生多態
1 public class Test{ 2 public static void main(String[] args){ 3 B1 b1 = new B1(); 4 B1 b2 = new B2(); //多態 5 C1 c = new C1(); 6 D1 d = new D1(); 7 D2 d2 = new D2(); 8 A a1 = new B2(); 9 System.out.println(b1 instanceof A); //可以通過編譯,因為A是可插拔的,B1的引用可以指向其子類對象,而其子類對象可能會實現了介面A(如B2),,但是運10 //行時就會檢驗了,結果為false (B1可能與A發生多態)11 System.out.println(b2 instanceof A);//結果為true (B2已經與A發生多態)12 // System.out.println(b1 instanceof C1); //編譯失敗,因為B與C之間不存在繼承關係 (C1不可能與C1存在多態,沒有繼承關係)13 // System.out.println(d1 instanceof A); //編譯失敗,因為D不可能有子類,不可能發生多態 (D1不可能與A多態,不可以有子類)14 System.out.println(d2 instanceof A); //編譯通過,結果為true (D2實現了A,與A產生了多態)15 System.out.println(new B1() instanceof A); //B1的匿名對象,false (B1可能與A發生多態)16 System.out.println(new B2() instanceof A); //B1的匿名對象,true (B2已經與A發生多態)17 // System.out.println(new B1(){} instanceof A);//B1的已經確定類體的,即匿名子類對象,不能通過編譯18 System.out.println(new B2(){} instanceof A);//B2的雖未匿名子類對象,但是卻屬於A的實作類別,所以編譯通過,結果為true19 // System.out.println(new B3() instanceof A); //抽象類別是不可以進行執行個體化的,編譯失敗20 // System.out.println(new B3(){} instanceof A);//抽象類別要產生匿名子類對象,必須複寫所有抽象方法,編譯失敗21 // System.out.println(new B3(){public void test(){}} instanceof A);//非A的匿名子類對象,編譯失敗22 System.out.println(new B4(){public void method(){}} instanceof A);//編譯通過,結果為true23 }24 }25 interface A{26 void method();27 }28 29 class B1{30 31 }32 class B2 extends B1 implements A{33 public void method(){}34 }35 abstract class B336 {37 abstract void test();38 }39 abstract class B4 implements A40 {41 42 }43 class C1{44 45 }46 final class D147 {48 }49 final class D2 implements A{50 public void method(){}51 }
3)介面與介面間,使用instanceof不存在編譯問題,但是若使用匿名內部類則會編譯失敗
1 public class Test{ 2 public static void main(String[] args){ 3 A a =new C(); 4 System.out.println(a instanceof B); //編譯通過.A可能與B發生多態,因為A的實作類別有可能實現了B,結果為false 5 System.out.println(new A(){public void test(){}} instanceof B);//編譯失敗,非B的匿名子類對象,不存在多態 6 } 7 } 8 interface A{ 9 }10 interface B{11 }12 class C implements A{13 }