目录
- 前言
- 1. obj 类型
- 1.1 obj不能为基本类型
- 1.2 obj 为 class 类的实例对象
- 1.3 obj 为 class 类的直接或间接子类
- 2. 实现策略
- 3. 实战
前言
Java中的一个双目运算符
本身也是一个关键字
主要用来测试一个对象是否为一个类的实例
主要的用法是:
obj instanceof Class
这个结果返回一个boolean类型
- 当 obj 为一个对象,Class 表示一个类或者一个接口
- 当 obj 为 Class 的对象、直接或间接子类、其接口实现类
以上代码的测试都是在编译期的,编译器会检查 obj 能否转换class类型,不能转换则直接报错,或者不能确定类型则通过编译。
1. obj 类型
1.1 obj不能为基本类型
当obj为基本类型的时候,编译会不通过
必须为引用类型,instanceof只能用作对象的判断
int i = 0;
System.out.println(i instanceof Integer);//编译不通过
System.out.println(i instanceof Object);//编译不通过
1.2 obj 为 class 类的实例对象
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
1.3 obj 为 class 类的直接或间接子类
这个比较重要
父类
class person {
}
子类
class Man extends person{
}
测试类如下
person p1 = new person();
person p2 = new Man();
Man m1 = new Man();
System.out.println(p1 instanceof Man);//false
System.out.println(p2 instanceof Man);//true
System.out.println(m1 instanceof Man);//true
截图如下
2. 实现策略
具体实现策略的算法如下:
1、obj如果为null,则返回false;否则设S为obj的类型对象,剩下的问题就是检查S是否为T的子类型;
2、如果S == T,则返回true;
3、接下来分为3种情况,之所以要分情况是因为instanceof要做的是“子类型检查”,而Java语言的类型系统里数组类型、接口类型与普通类类型三者的子类型规定都不一样,必须分开来讨论。
①、S是数组类型:如果 T 是一个类类型,那么T必须是Object;如果 T 是接口类型,那么 T 必须是由数组实现的接口之一;
②、接口类型:对接口类型的 instanceof 就直接遍历S里记录的它所实现的接口,看有没有跟T一致的;
③、类类型:对类类型的 instanceof 则是遍历S的super链(继承链)一直到Object,看有没有跟T一致的。遍历类的super链意味着这个算法的性能会受类的继承深度的影响。
3. 实战
调用子类的方法还是要进行强转换的
可以通过下面这个例子进行巩固强化
public class GenericTest01 {
public static void main(String[] args) {
// 使用JDK5之后的泛型机制
// 使用泛型List<Animal>之后,表示List集合中只允许存储Animal类型的数据。
// 用泛型来指定集合中存储的数据类型。
List<Animal> myList = new ArrayList<Animal>();
// 指定List集合中只能存储Animal,那么存储String就编译报错了。
// 这样用了泛型之后,集合中元素的数据类型更加统一了。
//myList.add("abc");
Cat c = new Cat();
Bird b = new Bird();
myList.add(c);
myList.add(b);
// 获取迭代器
// 这个表示迭代器迭代的是Animal类型。
Iterator<Animal> it = myList.iterator();
while(it.hasNext()){
// 使用泛型之后,每一次迭代返回的数据都是Animal类型。
//Animal a = it.next();
// 这里不需要进行强制类型转换了。直接调用。
//a.move();
// 调用子类型特有的方法还是需要向下转换的!
Animal a = it.next();
if(a instanceof Cat) {
Cat x = (Cat)a;
x.catchMouse();
}
if(a instanceof Bird) {
Bird y = (Bird)a;
y.fly();
}
}
}
}
class Animal {
// 父类自带方法
public void move(){
System.out.println("动物在移动!");
}
}
class Cat extends Animal {
// 特有方法
public void catchMouse(){
System.out.println("猫抓老鼠!");
}
}
class Bird extends Animal {
// 特有方法
public void fly(){
System.out.println("鸟儿在飞翔!");
}
}