詳解java中instanceof各種的用法


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的實現類,所以編譯通過,結果為true
19 //    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);//編譯通過,結果為true
23   }
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 B3
36 {
37   abstract void test();
38 }
39 abstract class B4 implements A
40 {
41 
42 }
43 class C1{
44 
45 }
46 final class D1
47 {
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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM