Java中,instanceof運算符的前一個操作符是一個引用變量,后一個操作數通常是一個類(可以是接口),用于判斷前面的對象是否是后面的類,或者其子類、實現類的實例。如
果是返回true,否則返回false。
也就是說:
使用instanceof關鍵字做判斷時, instanceof 操作符的左右操作數必須有繼承或實現關系
下面我們用繼承樹來判斷instanceof的返回值:
1 packageinstanceofTest;2
3 /**
4 *@authorzsh5 * @company wlgzs6 * @create 2019-03-21 19:557 * @Describe 繼承樹來判斷instanceof的返回值8 */
9 interfaceMan{}10 class Person1 implementsMan{}11 class Student extendsPerson1{}12 class Postgraduate extendsStudent {}13 classAnimal {}14 public classMain1 {15 public static voidmain(String[] args) {16 System.out.println("Student 的對象是誰的實例?");17 instanceofTest(newStudent());18 System.out.println("Animal 的對象是誰的實例?");19 instanceofTest(newAnimal());20 System.out.println("Postgraduate 的對象是誰的實例?");21 instanceofTest(newPostgraduate());22 //一個類的實例是這個類本身的實例,也是他父類,父類的父類的實例,也是實現的接口的實例
23 }24
25 public static voidinstanceofTest(Object p) {26 if (p instanceofAnimal)27 System.out.println(p.getClass() + "類的實例 是類Animal的實例");28 if (p instanceofPostgraduate)29 System.out.println(p.getClass() + "類的實例 是類Postgraduate的實例");30 if (p instanceofStudent)31 System.out.println(p.getClass() + "類的實例 是類Student的實例");32 if (p instanceofPerson1)33 System.out.println(p.getClass() + "類的實例 是類Person的實例");34 if (p instanceofMan)35 System.out.println(p.getClass() + "類的實例 是接口Man的實例");36 if (p instanceofObject)37 System.out.println(p.getClass() + "類的實例 是類Object的實例");38 }39 }
上面的程序,展示各類之間的關系的繼承樹是:
上述程序中:
由上面繼承樹可知,某個類(接口也可以看成一個特殊的類)的對象是不是其他類(或接口)的實例,只需按箭頭方向,以此對象所在的類為起點到達此繼承樹分支(可能有多個分支)終點,沿途經過的類(包括本類,或接口)就都是該對象的實例。
所以輸出結果是:
但是,要注意一點:
在判斷某個類(接口也可以看成一個特殊的類)的對象是不是其他類(或接口)的實例,一定要首先進行向上轉型,然后才可用instanceof關鍵字進行判斷,這是基本操作規范。
如:
1 packageinstanceofTest;2
3 /**
4 *@authorzsh5 * @company wlgzs6 * @create 2019-03-21 20:027 * @Describe8 */
9
10 interfaceA{11 voidsay();12 }13
14 class B implementsA{15 public voidsay()16 {17 System.out.println("B實現的say()方法");18 }19 }20
21 class C implementsA{22 public voidsay()23 {24 System.out.println("C實現的say()方法");25 }26 }27
28 public classMain2 {29 public static voidmain(String[] args) {30 A a= new B(); //接口不能new
31 System.out.println(a instanceof B); //true;發生了A a= new B();
32 System.out.println(a instanceof C); //false;沒有發生A a = new C();
33 }34 }
運行結果:
以上各類的之間關系的繼承樹如下:
在判斷接口A的對象a 是不是類C的實例時,沒有先進行向上轉型,就進行instanceof關鍵字的使用了,是肯定會返回false的。
測試用例:
1 packageinstanceofTest;2
3 /**
4 *@authorzsh5 * @company wlgzs6 * @create 2019-03-21 20:077 * @Describe instanceof 測試用例8 */
9 interfaceA{10
11 }12 class B implementsA{13
14 }15 class C extendsB{16
17 }18 public classMain3 {19 public static voidmain(String[] args) {20 A ab=newB();21 A ac=newC();22 B bc=newC();23 B bb=newB();24 C cc=newC();25 //對象實現一個接口,用這個對象和這個接口進行instanceof判斷,都為true。
26 System.out.println("ab instanceof A="+(ab instanceofA));27 System.out.println("ac instanceof A="+(ac instanceofA));28 System.out.println("bc instanceof A="+(bc instanceofA));29 System.out.println("bb instanceof A="+(bb instanceofA));30 System.out.println("cc instanceof A="+(cc instanceofA));31 //對象和父類進行instanceof判斷,都為true
32 System.out.println("ab instanceof B="+(ab instanceofB));33 System.out.println("ac instanceof B="+(ac instanceofB));34 System.out.println("bc instanceof B="+(bc instanceofB));35 System.out.println("bb instanceof B="+(bb instanceofB));36 System.out.println("cc instanceof B="+(cc instanceofB));37 //對象和他的子類進行instanceof判斷為false
38 System.out.println("ab instanceof C="+(ab instanceofC));39 System.out.println("ac instanceof C="+(ac instanceofC));40 System.out.println("bc instanceof C="+(bc instanceofC));41 System.out.println("bb instanceof C="+(bb instanceofC));42 System.out.println("cc instanceof C="+(cc instanceofC));43 }44 }
運行結果:
總結:
如果一個類的實例是這個類本身的實例,那么它也是它的父類、它的父類的父類的實例,也是由它實現的接口的實例
且instanceof左邊操作元顯式聲明的類型與右邊操作元必須是同種類或右邊是左邊父類的繼承關系
此外:
//false;這是instanceof 特 有 的 規 則 : 若左操作數為null, 結果就直接返回false, 不再運算右操作數是什么類。
boolean b5 = null instanceof String;
//編譯不通過;'A'在此處視為基本數據類型char,instanceof操作符只能用作對象的判斷
boolean b4 = 'A' instanceof Character;