深入分析java中的关键字instanceof

简介: instanceof关键字虽然没有final、static这些关键字用的多,但是也是非常重要的,尤其是面试。因此花了一些时间整理了一下。

一、认识instanceof关键字


其实instanceof就是一个操作符,语法形式很简单:

A instanceof B


A通常是引用变量,B通常是一个类或者是接口,表示的含义有三个:


(1)A是否是B的实例,

(2)A是否是B子类的实例

(3)A是否是B接口实现类的实例


也就是说我们平时使用instanceof关键字一般作为判断左右两侧是否有继承或者是实现关系。带着上面的问题,下面我们就具体看看如何去使用这个关键字。


二、使用instanceof关键字


为了表述上面三个含义,我们先给出一个继承关系图,然后去实现。

v2-ffb104872ded541e8fe636faaaf4a094_1440w.jpg

上面这张类图继承关系已经很明确了,我们用代码看一下:


三、代码验证


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是如何实现的就好。

相关文章
|
7月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
243 4
|
11月前
|
监控 Java Unix
6个Java 工具,轻松分析定位 JVM 问题 !
本文介绍了如何使用 JDK 自带工具查看和分析 JVM 的运行情况。通过编写一段测试代码(启动 10 个死循环线程,分配大量内存),结合常用工具如 `jps`、`jinfo`、`jstat`、`jstack`、`jvisualvm` 和 `jcmd` 等,详细展示了 JVM 参数配置、内存使用、线程状态及 GC 情况的监控方法。同时指出了一些常见问题,例如参数设置错误导致的内存异常,并通过实例说明了如何排查和解决。最后附上了官方文档链接,方便进一步学习。
2387 4
|
5月前
|
存储 Java Go
【Java】(3)8种基本数据类型的分析、数据类型转换规则、转义字符的列举
牢记类型转换规则在脑海中将编译和运行两个阶段分开,这是两个不同的阶段,不要弄混!
302 2
|
5月前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
282 1
|
6月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
7月前
|
机器学习/深度学习 安全 Java
Java 大视界 -- Java 大数据在智能金融反洗钱监测与交易异常分析中的应用(224)
本文探讨 Java 大数据在智能金融反洗钱监测与交易异常分析中的应用,介绍其在数据处理、机器学习建模、实战案例及安全隐私等方面的技术方案与挑战,展现 Java 在金融风控中的强大能力。
|
9月前
|
数据采集 搜索推荐 算法
Java 大视界 -- Java 大数据在智能教育学习社区用户互动分析与社区活跃度提升中的应用(274)
本文系统阐述 Java 大数据技术在智能教育学习社区中的深度应用,涵盖数据采集架构、核心分析算法、活跃度提升策略及前沿技术探索,为教育数字化转型提供完整技术解决方案。
|
8月前
|
存储 Java 大数据
Java 大视界 -- Java 大数据在智能家居能源消耗模式分析与节能策略制定中的应用(198)
简介:本文探讨Java大数据技术在智能家居能源消耗分析与节能策略中的应用。通过数据采集、存储与智能分析,构建能耗模型,挖掘用电模式,制定设备调度策略,实现节能目标。结合实际案例,展示Java大数据在智能家居节能中的关键作用。
|
9月前
|
Java 数据库连接 API
互联网大厂校招 JAVA 工程师笔试题解析及常见考点分析
本文深入解析互联网大厂校招Java工程师笔试题,涵盖基础知识(数据类型、流程控制)、面向对象编程(类与对象、继承与多态)、数据结构与算法(数组、链表、排序算法)、异常处理、集合框架、Java 8+新特性(Lambda表达式、Stream API)、多线程与并发、IO与NIO、数据库操作(JDBC、ORM框架MyBatis)及Spring框架基础(IoC、DI、AOP)。通过技术方案讲解与实例演示,助你掌握核心考点,提升解题能力。
365 2
|
10月前
|
人工智能 Java
Java参数传递分析
本文详细探讨了Java中参数传递的机制,明确指出Java采用的是值传递而非引用传递。通过基本数据类型(如int)和引用类型(如Map、自定义对象People)的实例测试,证明方法内部对参数的修改不会影响原始变量。即使在涉及赋值返回的操作中,表面上看似引用传递,实际仍是值传递的结果。文中结合代码示例与执行结果,深入解析了值传递的本质及容易引起混淆的情形,帮助读者准确理解Java参数传递的核心概念。
210 7