【Java 基础】-- instanceof 用法详解
1. instanceof 关键字
如果你之前一直没有怎么仔细了解过instanceof
关键字,现在就来了解一下:
<img src="https://markdownpicture.oss-cn-qingdao.aliyuncs.com/blog/20201129214016.png" style="zoom:50%;" />
instanceof
其实是 java 的一个二元操作符,和=
,<
,>
这些是类似的,同时它也是被保留的关键字,主要的作用,是为了测试左边的对象,是不是右边的类的实例,返回的是 boolean 值。
注意:A
是实例,而B
则是Class类
下面使用代码测试一下:
输出结果如下:
从上面的结果,其实我们可以看出instanceof
,相当于判断当前对象能不能装换成为该类型,java
里面上转型是安全的,子类对象可以转换成为父类对象,接口实现类对象可以装换成为接口对象。
对象a
和Interface
没有什么关系,所以返回false
。
那如果我们装换成为 Object 了,它还能认出来是哪一个类的对象么?
上面的结果返回都是true
,也就是认出来还是哪一个类的对象。同时我们使用String
对象测试的时候,发现对象既是String
的实例,也是Object
的实例,也印证了Java
里面所有类型都默认继承了Obejct
。
但是值得注意的是,我们只能使用对象来instanceof
,不能使用基本数据类型,否则会报错。
如果对象为null
,那是什么类型?
这个答案是:不知道什么类型,因为null
可以转换成为任何类型,所以不属于任何类型,instanceof
结果会是false
。
具体的实现策略我们可以在官网找到:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.instanceof
如果S
是objectref
所引用的对象的类,而T
是已解析类,数组或接口的类型,则instanceof
确定是否 objectref
是T
的一个实例。S s = new A(); s instanceof T
如果 S 是一个普通的(非数组)类,则:
- 如果 T 是一个类类型,那么 S 必须是 T 的同一个类,或者 S 必须是 T 的子类;
- 如果 T 是接口类型,那么 S 必须实现接口 T。
如果 S 是接口类型,则:
- 如果 T 是类类型,那么 T 必须是 Object。
- 如果 T 是接口类型,那么 T 一定是与 S 相同的接口或 S 的超接口。
如果 S 是表示数组类型 SC 的类[],即类型 SC 的组件数组,则:
- 如果 T 是类类型,那么 T 必须是 Object。
- 如果 T 是一种接口类型,那么 T 必须是数组实现的接口之一(JLS§4.10.3)。
- 如果 T 是一个类型为 TC 的数组[],即一个类型为 TC 的组件数组,那么下列其中一个必须为真:
- TC 和 SC 是相同的原始类型。
- TC 和 SC 是引用类型,类型 SC 可以通过这些运行时规则转换为 TC。
但是具体的底层原理我在知乎找到的 R 大 回答的相关问题,https://www.zhihu.com/question/21574535,看完觉得我太弱了...我是菜鸟...我确实是菜鸟
2. isInstance()方法
其实这个和上面那个是基本相同的,主要是这个调用者是Class
对象,判断参数里面的对象是不是这个Class
对象的实例。
历史总是惊人的相似!!!
事实证明,这个isInstance(o)
判断的是o
是否属于当前Class
类的实例.
不信?再来测试一下:
可以看出,其实就是装换成为Object
,之前的类型信息还是会保留着,结果和instance
一样,区别是:
instanceof
:前面是实例对象,后面是类型isInstance
:调用者(前面)是类型对象,参数(后面)是实例对象
但是有一个区别哦😯,isInstance()
这个方法,是可以使用在基本类型上的,其实也不算是用在基本类型,而是自动做了装箱操作。看下面👇:
参数里面的 1,其实会被装箱成为new Integer(1)
,所以这样用不会报错。
3. instanceof,isInstance,isAssignableFrom 区别是什么?
instanceof
判断对象和类型之间的关系,是关键字,只能用于对象实例,判断左边的对象是不是右边的类(包括父类)或者接口(包括父类)的实例化。isInstance(Object o)
:判断对象和类型之间的关系,判断o
是不是调用这个方法的class
(包括父类)或者接口(包括父类)的实例化。isAssignableFrom
:判断的是类和类之间的关系,调用者是否可以由参数中的Class
对象转换而来。
注意:java
里面一切皆是对象,所以,class
本身也是对象。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。
此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~
版权声明: 本文为 InfoQ 作者【秦怀杂货店】的原创文章。
原文链接:【http://xie.infoq.cn/article/e72831c9afc5d726b73bcc9fa】。文章转载请联系作者。
评论