乐趣区

关于instanceof: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外面上转型是平安的,子类对象能够转换成为父类对象,接口实现类对象能够装换成为接口对象。

对象 aInterface没有什么关系,所以返回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/javas…

如果 Sobjectref所援用的对象的类,而 T 是已解析类,数组或接口的类型,则 instanceof 确定是否 objectrefT 的一个实例。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/questio…

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自身也是对象。

【作者简介】
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使迟缓,驰而不息。这个世界心愿所有都很快,更快,然而我心愿本人能走好每一步,写好每一篇文章,期待和你们一起交换。

此文章仅代表本人(本菜鸟)学习积攒记录,或者学习笔记,如有侵权,请分割作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有谬误之处,还望指出,感激不尽~

退出移动版