概念:
instanceof判定一个对象是否为指定类的实例
用法:
boolean object instanceof class/interface/Array
instanceof的右侧可以是类、接口、数组
原理:
1.instanceof左边必须为引用类型或null,否则运行时会报错,而右边不能为null
2.instanceof的左边必须为可具体化的类型,即不能为泛型,否则编译时报错
3.如果左边强转右边类型失败,则返回false
用Java代码表示如下:
boolean res;
if(obj == null)
return false;
else{
try{
T test = (T)obj;
return true;
}catch(ClassCastExcetion e){
return = false;
}
}
从JVM角度来分析instanceof的实现
根据Java指令集:https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.instanceof
instanceof
操作
判定一个对象是否为指定类的实例
指令格式
instanceof
indexbyte1
indexbyte2
指令执行前后的栈顶状态
…, objectref →
…, result
描述
objectref必须为引用类型,可以是类、数组的实例、或接口。 indexbyte1 和 indexbyte2用于构造对当前类的运行常量池的索引。
如果objectref为null, instanceof指令将0压入栈顶。
对indexbyte1和indexbyte2构造的运行时常量池索引进行解析,解析类、接口或数组引用名, 如果objectref 是已解析类或数组的实例、或实现了对应接口,则instanceof指令将1压入栈顶,否则压入0。
以下是详细解释,即objectref不为null且是对应的解析类型:
如果object的类是S且objecytef是S类的引用对象, T 是解析的类/ 数组/接口类型,instanceof 确定objectref是否是T类型的,举例如下:
- 如果 S 是非数组类, 则:
如果T是类类型, 则S必须与T为同一类或是T的子类;
如果T为接口类型,则S必须是T接口的实现。 - 如果S是接口类型,则:
如果T为类类型,则T必须为Object类;
如果T为接口类型,则S必须与T为同一接口或T为S的超接口。 - 如果S为代表SC[]的类,即S为SC,则:
如果T为类类型,则必须为O
如果T为接口类型,则T必须为数组以实现的接口类之一;
如果T为数组TC[],即为数组的元素TC类,则必须满足下列条件之一:
1.TC和SC必须为基础类型
2.TC和SC均为引用类型,SC可以转换为TC