Java instanceof 关键词

问:下面程序有什么问题吗?运行结果是什么?
        "demo" instanceof Object; //1,true

        new String() instanceof String; //2,true
        new Object() instanceof String; //3,false
        'A' instanceof Character; //4,编译报错
        null instanceof String; //5, false 
        (String) null instanceof String; //6,false
        new Date() instanceof String; //7,false

        class GenericClass<T> {
            public boolean isDateInstance(T t) {
                return t instanceof Date;
            }
        }
        new GenericClass<String>().isDateInstance(""); //8,false

        "demo" instanceof null; //9,编译错误

        class B {
        }

        class A {
        }
        new B() instanceof A; //10,编译错误
        String str[] = new String[2];
        str instanceof String[]; //11,true

答:答案如题目后面注释所示,解释如下描述。

注释 1 的返回值是 true,"demo" 是一个字符串,字符串继承自 Object,所以返回 true。

注释 2 的返回值是 true,因为一个类的对象当然是它的实例了。

注释 3 的返回值是 false,因为 Object 是父类,其对象当然不是 String 类的实例了,要注意的是这句话是可以编译通过的,只要 instanceof 关键字的左右两个操作数有继承或实现关系就可以编译通过。

注释 4 编译不通过,因为 'A' 是一个 char 类型,也就是一个基本类型,不是一个对象,instanceof 只能用于对象的判断,不能用于基本类型的判断。

注释 5 返回值是 false,因为这是 instanceof 特有的规则,若左操作数是 null 则结果直接返回 false,不再运算右操作数是什么类,这和我们经常用到的 equals、toString 方法不同。

注释 6 返回值是 false,因为 null 没有类型,所以即使做类型转换还是 null。

注释 7 编译通不过,因为 Date 类和 String 没有继承或实现关系,所以在编译时直接就报错了,instanceof 操作符的左右操作数必须有继承或实现关系,否则编译会失败。

注释 8 返回值是 false,因为虽然 T 是 String 类型且与 Date 之间没有继承或实现关系,但是 Java 泛型在编译成字节码时 T 已经被换成了 Object 类型了(泛型擦除),传递的实参是 String 类型而已。

注释 9 编译不通过,instanceof 的右操作符必须是一个接口或者类,null 啥都不是,所以咯。

注释 10 编译通不过,因为 Date 类和 String 没有继承或实现关系,所以在编译时直接就报错了,instanceof 操作符的左右操作数必须有继承或实现关系,否则编译会失败。

注释 11 返回值为 true,因为数组类型也可以使用 instanceof 来判断。

问:说说 java 的 instanceof 与 obj.instanceof(class) 的区别?

答:java 中的 instanceof 运算符用来在运行时指出对象是否是特定类的一个实例,通过返回一个布尔值来指出这个对象是否是这个特定类或者是它的子类的一个实例;用法为 result = object instanceof class,参数 result 布尔类型,object 为必选项的实例,class 为必选项的任意已定义的对象类,如果 object 是 class 的一个实例则 instanceof 运算符返回 true,如果 object 不是指定类的一个实例或者 object 是 null 则返回 false;但是 instanceof 在 java 的编译状态和运行状态是有区别的,在编译状态中 class 可以是 object 对象的父类、自身类、子类,在这三种情况下 java 编译时不会报错,在运行转态中 class 可以是 object 对象的父类、自身类但不能是子类,当为父类、自身类的情况下 result 结果为 true,为子类的情况下为 false。

clazz.inInstance(obj) 表明这个对象能不能被转化为这个类,一个对象是本身类的一个对象,一个对象能被转化为本身类所继承类(父类的父类等)和实现的接口(接口的父接口)强转,所有对象都能被 Object 强转,当 obj 参数为 null 时一定为 false。

具体区别可以参见如下例子:

        class A {
        }

        class B extends A {
        }

        B b = new B();
        A a = new A();
        A ba = new B();
        b instanceof B; //true 
        b instanceof A; //true 
        b instanceof Object; //true 
        null instanceof Object; //false 
        b.getClass().isInstance(b); //true 
        b.getClass().isInstance(a); //false 
        a.getClass().isInstance(ba); //true 
        b.getClass().isInstance(ba); //true 
        b.getClass().isInstance(null); //false 

        A.class.isInstance(a); //true 

        A.class.isInstance(b); //true 

        A.class.isInstance(ba); //true 

        B.class.isInstance(a); //false 

        B.class.isInstance(b); //true 

        B.class.isInstance(ba); //true 

        Object.class.isInstance(b); //true 

        Object.class.isInstance(null); //false
问:说说 java 的 instanceof 与 clazz.getClass() 的区别?

答:instanceof 进行类型检查规则是你属于该类吗?或者你属于该类的派生类吗?而 obj.getClass() 获得类型信息采用 == 来进行检查是否相等的操作是严格比较,不存在继承方面的考虑。具体区别样例参见如下:

        class A {
        }
        class B extends A {
        }
        new A() instanceof A; //true 
        new A() instanceof B; //false 
        new A().getClass() == A.class; //true 
        new A().getClass() == B.class; //false 
        new B() instanceof A; //true 
        new B() instanceof B; //true 
        new B().getClass() == A.class; //false
        new B().getClass() == B.class; //true
问:简单说说 java 的 instanceof 实现原理?

答:这个题的答案取决于你面试什么岗位,如果是 Android 的话其实如下答案就差不多了,如果是高级后台开发那就需要更加深度的回答了。

首先 instanceof 直接对应一条虚拟机指令 instanceof 且为 java 语法保留关键字,而非通过反射实现;instanceof 在底层实现上维护了主要超类型(继承深度)小于一个固定数值(一般为 7)的主数组和次要超类型(判断的时候需要 super 链遍历查找),然后在字节码使用特殊指令对常量池中的相关符号引用进行判断,从而来决定是否某个类或者派生类,以此返回 true 或 false。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,625评论 18 399
  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,261评论 0 16
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,054评论 0 4
  • 文/倾国不倾城 每个人都应该把自己当作品牌来经营,你的每一次亮相、说过的每一句话、做过的每一件事,上面都标志着...
    倾国不倾城阅读 486评论 0 0