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;