一、认识instanceof关键字
其实instanceof就是一个操作符,语法形式很简单:
A instanceof B
A通常是引用变量,B通常是一个类或者是接口,表示的含义有三个:
(1)A是否是B的实例,
(2)A是否是B子类的实例
(3)A是否是B接口实现类的实例
也就是说我们平时使用instanceof关键字一般作为判断左右两侧是否有继承或者是实现关系。带着上面的问题,下面我们就具体看看如何去使用这个关键字。
二、使用instanceof关键字
为了表述上面三个含义,我们先给出一个继承关系图,然后去实现。
上面这张类图继承关系已经很明确了,我们用代码看一下:
三、代码验证
interface Play{} class Human{} class Man extends Human implements Play{} class Soldier extends Man {} class Woman extends Human {} public class Test { public static void main(String[] args) { //把这几个类的实例都创建出来 Human human=new Human(); Man man = new Man(); Woman woman=new Woman(); Soldier soldier = new Soldier(); //然后我们挨个测试一下 //1、Human是谁的实例 test(new Human()); //2、Man是谁的实例 test(new Man()); //3、Soldier是谁的实例 test(new Soldier()); //4、Woman是谁的实例 test(new Woman()); } public static void test(Object p) { if (p instanceof Human) System.out.println(p.getClass() + " 是类Human的实例"); if (p instanceof Man) System.out.println(p.getClass() + " 是类Man的实例"); if (p instanceof Soldier) System.out.println(p.getClass() + " 是类Soldier的实例"); if (p instanceof Woman) System.out.println(p.getClass() + " 是类Woman的实例"); if (p instanceof Play) System.out.println(p.getClass() + " 是接口Play的实例"); } }
在这里我们对四个类进行了测试。下面我们输出一下结果:
(1)Human是谁的实例呢?
在文章一开始我们已经给出,Human其实是一个根类,没有继承任何父类,也没有实现任何接口。所以他的输出也很简单
class com.fdd.instanceofTest.Human 是类Human的实例
他自己只能是自己的实例了。
(2)Man是谁的实例?
Man继承了Human,实现了Play接口,因此他是Human的实例,同时也是Play接口的实例。
class com.fdd.instanceofTest.Man 是类Human的实例 class com.fdd.instanceofTest.Man 是类Man的实例 class com.fdd.instanceofTest.Man 是接口Play的实例
(3)Soldier是谁的实例?
Soldier继承了Man类,但是这里却没有实现Play接口,我们先看一下输出吧。
class com.fdd.instanceofTest.Soldier 是类Human的实例 class com.fdd.instanceofTest.Soldier 是类Man的实例 class com.fdd.instanceofTest.Soldier 是类Soldier的实例 class com.fdd.instanceofTest.Soldier 是接口Play的实例
也就是说,父亲有的儿子也有,父类实现的接口,子类也默认实现了。
(4)Woman是谁的实例?
如果你理解了上面的Man,那么Woman你应该能够理解,Woman只继承了Human类,所以他应该有两个,一个是Human的实例,一个是自己的实例
class com.fdd.instanceofTest.Woman 是类Human的实例 class com.fdd.instanceofTest.Woman 是类Woman的实例
四、总结
instanceof关键字用起来还是比较简单的,还记得我们在文章一开始提出的三个含义嘛?现在我们给其解答一下:
(1)A是A本身的实例,
(2)A是A父类(或者是父类的父类)的实例
(3)A是A接口(或者是父类的接口)的实例
既然instanceof是一个关键字,那说明jvm虚拟机能够正确的识别这个java指令。那么jvm如何去识别呢?
instanceof的指令格式是:instanceof|indexbyte1|indexbyte2。
指令执行前后的栈顶状态:objectref=>。。。
indexbyte1和indexbyte2用于构造对当前类的常量池的索引,objectref为reference类型,可以是某个类,数组的实例或者是接口。在实现instanceof指令的时候,首先是对indexbyte1和indexbyte2构造的常量池索引进行解析,然后根据java规范判断解析的类是不是objectref的一个实例,最后在栈顶写入结果。
这一段看不懂没关系,这是在jvm的操作,一般面试的时候要是问道,你只要把其如何使用搞清楚就好了,非要显得牛逼一点,那就看看instanceof指令在jvm是如何实现的就好。