java之instanceof用法详细分析

2023-10-31 08:34:54

前言

Java中的一个双目运算符
本身也是一个关键字
主要用来测试一个对象是否为一个类的实例

主要的用法是:

objinstanceofClass

这个结果返回一个boolean类型

  • 当 obj 为一个对象,Class 表示一个类或者一个接口
  • 当 obj 为 Class 的对象、直接或间接子类、其接口实现类

以上代码的测试都是在编译期的,编译器会检查 obj 能否转换class类型,不能转换则直接报错,或者不能确定类型则通过编译。

1. obj 类型

1.1 obj不能为基本类型

当obj为基本类型的时候,编译会不通过
必须为引用类型,instanceof只能用作对象的判断

int i=0;System.out.println(iinstanceofInteger);//编译不通过System.out.println(iinstanceofObject);//编译不通过

1.2 obj 为 class 类的实例对象

Integer integer=newInteger(1);System.out.println(integerinstanceofInteger);//true

1.3 obj 为 class 类的直接或间接子类

这个比较重要
父类

class person{}

子类

classManextends person{}

测试类如下

person p1=newperson();
person p2=newMan();Man m1=newMan();System.out.println(p1instanceofMan);//falseSystem.out.println(p2instanceofMan);//trueSystem.out.println(m1instanceofMan);//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. 实战

调用子类的方法还是要进行强转换的
可以通过下面这个例子进行巩固强化

publicclassGenericTest01{publicstaticvoidmain(String[] args){// 使用JDK5之后的泛型机制// 使用泛型List<Animal>之后,表示List集合中只允许存储Animal类型的数据。// 用泛型来指定集合中存储的数据类型。List<Animal> myList=newArrayList<Animal>();// 指定List集合中只能存储Animal,那么存储String就编译报错了。// 这样用了泛型之后,集合中元素的数据类型更加统一了。//myList.add("abc");Cat c=newCat();Bird b=newBird();

        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(ainstanceofCat){Cat x=(Cat)a;
                x.catchMouse();}if(ainstanceofBird){Bird y=(Bird)a;
                y.fly();}}}}classAnimal{// 父类自带方法publicvoidmove(){System.out.println("动物在移动!");}}classCatextendsAnimal{// 特有方法publicvoidcatchMouse(){System.out.println("猫抓老鼠!");}}classBirdextendsAnimal{// 特有方法publicvoidfly(){System.out.println("鸟儿在飞翔!");}}
  • 作者:码农研究僧
  • 原文链接:https://blog.csdn.net/weixin_47872288/article/details/120671903
    更新时间:2023-10-31 08:34:54