1. instanceof关键字
如果你之前始终没有怎么认真理解过instanceof
关键字,当初就来理解一下:
instanceof
其实是java的一个二元操作符,和=
,<
,>
这些是相似的,同时它也是被保留的关键字,次要的作用,是为了测试右边的对象,是不是左边的类的实例,返回的是boolean值。
A instanceof B
留神:A
是实例,而B
则是Class类
上面应用代码测试一下:
class A{}interface InterfaceA{}class B extends A implements InterfaceA{}public class Test { public static void main(String[] args) { B b = new B(); System.out.println(b instanceof B); System.out.println(b instanceof A); System.out.println(b instanceof InterfaceA); A a = new A(); System.out.println(a instanceof InterfaceA); }}
输入后果如下:
truetruetruefalse
从下面的后果,其实咱们能够看出instanceof
,相当于判断以后对象能不能装换成为该类型,java
外面上转型是平安的,子类对象能够转换成为父类对象,接口实现类对象能够装换成为接口对象。
对象a
和Interface
没有什么关系,所以返回false
。
那如果咱们装换成为Object了,它还能认出来是哪一个类的对象么?
public class Test { public static void main(String[] args) { Object o = new ArrayList<Integer>(); System.out.println(o instanceof ArrayList); String str = "hello world"; System.out.println(str instanceof String); System.out.println(str instanceof Object); }}
下面的后果返回都是true
,也就是认出来还是哪一个类的对象。同时咱们应用String
对象测试的时候,发现对象既是String
的实例,也是Object
的实例,也印证了Java
外面所有类型都默认继承了Obejct
。
然而值得注意的是,咱们只能应用对象来instanceof
,不能应用根本数据类型,否则会报错。
如果对象为null
,那是什么类型?
这个答案是:不晓得什么类型,因为null
能够转换成为任何类型,所以不属于任何类型,instanceof
后果会是false
。
具体的实现策略咱们能够在官网找到:https://docs.oracle.com/javas...
如果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/questio...
2. isInstance()办法
其实这个和下面那个是基本相同的,次要是这个调用者是Class
对象,判断参数外面的对象是不是这个Class
对象的实例。
class A {}interface InterfaceA {}class B extends A implements InterfaceA {}public class Test { public static void main(String[] args) { B b = new B(); System.out.println(B.class.isInstance(b)); System.out.println(A.class.isInstance(b)); System.out.println(InterfaceA.class.isInstance(b)); A a = new A(); System.out.println(InterfaceA.class.isInstance(a)); }}
历史总是惊人的类似!!!
truetruetruefalse
事实证明,这个isInstance(o)
判断的是o
是否属于以后Class
类的实例.
不信?再来测试一下:
public class Test { public static void main(String[] args) { String s = "hello"; System.out.println(String.class.isInstance(s)); // true System.out.println(Object.class.isInstance(s)); // true System.out.println("============================="); Object o = new ArrayList<String>(); System.out.println(String.class.isInstance(o)); // false System.out.println(ArrayList.class.isInstance(o)); // true System.out.println(Object.class.isInstance(o)); // true }}
能够看出,其实就是装换成为Object
,之前的类型信息还是会保留着,后果和instance
一样,区别是:
instanceof
:后面是实例对象,前面是类型isInstance
:调用者(后面)是类型对象,参数(前面)是实例对象
然而有一个区别哦????,isInstance()
这个办法,是能够应用在根本类型上的,其实也不算是用在根本类型,而是主动做了装箱操作。看上面????:
System.out.println(Integer.class.isInstance(1));
参数外面的1,其实会被装箱成为new Integer(1)
,所以这样用不会报错。
3. instanceof,isInstance,isAssignableFrom区别是什么?
instanceof
判断对象和类型之间的关系,是关键字,只能用于对象实例,判断右边的对象是不是左边的类(包含父类)或者接口(包含父类)的实例化。isInstance(Object o)
:判断对象和类型之间的关系,判断o
是不是调用这个办法的class
(包含父类)或者接口(包含父类)的实例化。isAssignableFrom
:判断的是类和类之间的关系,调用者是否能够由参数中的Class
对象转换而来。
留神:java
外面所有皆是对象,所以,class
自身也是对象。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使迟缓,驰而不息。这个世界心愿所有都很快,更快,然而我心愿本人能走好每一步,写好每一篇文章,期待和你们一起交换。
此文章仅代表本人(本菜鸟)学习积攒记录,或者学习笔记,如有侵权,请分割作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有谬误之处,还望指出,感激不尽~