【Java基础】-- instanceof 用法详解
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);
}
}
输出结果如下:
true
true
true
false
从上面的结果,其实我们可以看出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/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
对象的实例。
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));
}
}
历史总是惊人的相似!!!
true
true
true
false
事实证明,这个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
本身也是对象。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。
此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~
【Java基础】-- instanceof 用法详解的更多相关文章
- Java基础之 数组详解
前言:Java内功心法之数组详解,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 数组概念 同一种类型数据的集合.其实数组就是一个容器. 数组 ...
- java基础之:详解内部类(转载)
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面 ...
- java中的instanceof用法详解
instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字.它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据.用它来判断某个对象是否是某个Clas ...
- [Java基础] Java enum的用法详解
用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...
- 多线程java的concurrent用法详解(转载)
我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,当然也有一些开源的框架提供了这些功能,但是这些依然没有JDK自带的功能使用起来方便.而当针对高质量Java ...
- java的concurrent用法详解
我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,当然也有一些开源的框架提供了这些功能,但是这些依然没有JDK自带的功能使用起来方便.而当针对高质量Java ...
- 【转】Java enum的用法详解
用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...
- Java enum的用法详解[转]
Ref:http://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html 用法一:常量 在JDK1.5 之前,我们定义常量都是: p ...
- Java enum的用法详解
(转自:http://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html) 用法一:常量 在JDK1.5 之前,我们定义常量都是: ...
- Java基础(52):ClassCastException详解(转)
ClassCastException,从字面上看,是类型转换错误,通常是进行强制类型转换时候出的错误.下面对产生ClassCastException异常的原因进行分析,然后给出这种异常的解决方法. 这 ...
随机推荐
- 常见的 HTTP Status Codes
前言 网页开发做久了, 自然而且会接触到许多 status code. 这篇列出一些常见的 status code. 初学者可以把它们学上来. 真的很常见哦. 参考 Wikipedia – List ...
- 系统编程-操作系统概论PART1
Part1. 计算机的基本组成原理 Part2. 计算机执行原理顶层视图 Part3. 指令 指令周期 取指令和执行指令 指令格式 前面1字节是操作码,代码指令的功能,例如加法功能. 后面3字节用于寻 ...
- 反问面试官3个ThreadLocal的问题
ThreadLocal,一个Java人面试绕不开的话题,我也很奇怪为什么那些面试官很喜欢问这个,也不知道他们自己有没有搞清楚. 接下来,我想先说说ThreadLocal的用法和使用场景,然后反问面试官 ...
- 数组 findIndex 方法去重
思路:先使用 findIndex 找到重复元素的下标,然后使用 splice 方法删除 :
- 58. vue常用的api
1. nextTick 使用场景:通过异步渲染的页面解构不能直接dom操作,要使用 nextTick (延迟回调)等待一下 :nextTick 的作用:感知dom的更新完成,类似于 updated ...
- Android复习(三)清单文件中的元素——> activity
转自: https://developer.android.google.cn/guide/topics/manifest/activity-element <activity> 语法: ...
- 如何集成化管理API_方便企业内外部调用?
API 已成为企业数字战略中不可或缺的一部分.它们使不同软件系统.应用程序和服务之间能够高效.灵活地相互沟通.API不仅能提升企业内部各部门之间的协作效率,还能加强与外部合作伙伴及客户之间的互动. A ...
- day13-JavaDoc
JavaDoc JavaDoc命令是用来生成自己API文档的 参数信息 @author 作者名 @version 版本号 @since 指明需要最早使用的jdk版本 @param 参数名 @retur ...
- JOI 2018 Final
A - ストーブ (Stove) 有 \(n\) 个客人将要来访,第 \(i\) 个客人的来访时间为 \([a_i, a_i + 1]\),保证 \(\forall i \in [1, n), a_i ...
- Java中重写equals并重写hashcode方法的描述
1.两个对象的hashCode()相同,equals()不一定为true (1)重写equals()的同时,重写hashCode() a.定义Person类,私有属性name,age:有参构造,set ...