从instanceof的特殊情况说起
在阅读相关课件时,发现了一个有趣的注释:“避免使用instanceof子类”。因此我做了一个小实验,对于父类和子类互相instanceof查看结果:
- 子类 instanceof 父类 == true
- 父类 instanceof 子类 == false
除此之外,instanceof也不需要进行null检查。这些特性让人不禁好奇,其具体的实现原理。
基本原理思想
查阅相关资料,得到了一个如下思路的代码
//obj instanceof T
instanceof_(obj,T){
boolean rs;
if (obj == null) {
rs= false;
} else {
try {
T temp = (T) obj;
rs= true;
} catch (ClassCastException e) {
rs = false;
}
}
return rs;
}
可以看到首先是对类型进行了null检查,这也解释了为何不需要提前进行null检查。其次判断类型使用了类型转换,一般向上转型是没有问题的,向下转向会引发ClassCastException。这也说明了子类 instanceof 父类 == true,父类 instanceof 子类 == false。因此我们在使用instanceof时要注意二者的继承关系。
对强转的解释
为什么不引发ClassCastException就为true?
- 设S为obj的类型对象, 检查S是否为T的子类型;
- 如果S == T,则返回true;否则进行子类型检查:
- S是数组类型:如果 T 是一个类类型,那么T必须是Object;如果 T 是接口类型,那么 T 必须是由数组实现的接口之一;
- S是接口类型:遍历S所实现的接口,看有没有跟T一致的;
- S是类类型:遍历S的super链(继承链)一直到Object,看有没有跟T一致的。(遍历类的super链意味着这个算法的性能会受类的继承深度的影响。)
以上只要有一个成立,S就是T的子类型
否则 S不是T的子类型。那么就无法强制转换,会产生ClassCastException。