Java关键字——Instanceof的用法

    Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。

用法: 
    result = object instanceof class 
参数: 
    Result:布尔类型。 
    Object:必选项。任意对象表达式。 
    Class:必选项。任意已定义的对象类。 
说明: 
    如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。

    但是instanceof在Java的编译状态和运行状态是有区别的:

    在编译状态中,class可以是object对象的父类,自身类,子类。在这三种情况下Java编译时不会报错。

    在运行状态中,class可以是object对象的父类,自身类,不能是子类。在前两种情况下result的结果为true,最后一种为false。但是class为子类时编译不会报错。运行结果为false。

    上面是理论说明,下面贴出测试代码,进行具体说明。

        /**
 * @author zhaoxin
 * @Date 2016年12月13日 下午2:29:32
 * @Description 
 *
 */

public class TestInstanceOf {
    public static void main(String[] args) {
        boolean b1 = "String" instanceof Object;
        boolean b2 = new String() instanceof String;
        boolean b3 = new Object() instanceof String;
        boolean b4 = 'A' instanceof Character;
        boolean b5 = null instanceof String;
        boolean b6 = (String)null instanceof String;
        boolean b7 = new Date() instanceof String;
        boolean b8 = new GenericClass<String>().isDateInstance("");

    }
}


class GenericClass<T>{
    public boolean isDateInstance(T t){
        return t instanceof Date;
    }
}


    大家可以可以在看答案之前先自己做一下,基本上面的代码。instanceof 所有的应用场景都出现,看看能答对几个。

    好了,现在公布答案:

  •     "String" instanceof Object

               返回值为true: 这很正常,"String"是一个字符串,字符串继承Object对象,按上面的理论来说,"String"字符串是Object的子类,编译器不会报错,运行结果为true;

  •     new String() instanceof String

               返回值为true:按照instanceof的定义来看,一个类的对象当然是他的实例了,结果为true。

  •     new Object instanceof String

               返回值为false:Object是String的父类,其对象不能是String类的实例。但是这条语句完全可以编译通过,只要instanceof关键字的左右两个操作数有继承或实现关系,,就可以编译通过。

  •     'A' instanceof Character

               这句话有可能用户会说是true,也有可能会说是false。事实上,该条语句它编译不通过,为什么呢?因为'A'是一个char类型,是一个基本类型(java的八大基本类型就不说了),不是一个对象,instanceof只能用于对象的判断,不能用于基本类型的判断。

  •     null instanceof String 

                返回值为false:上面理论讲解的时候有说过,左边的object为null时,结果返回false。这是instanceof特有的一个规则。有了这个规则我们在使用instanceof操作符时,不用关心被判断的类(也就是左操作数)是否为null,这与我们经常用到的equals、toString方法不同。

  •     (String)null instanceof String 

                返回值为false:有人会觉得因为有强转,结果会是true。这是一个错误的理解,null是一个万用的类型,可以说它是没有类型,即使做完类型转换还是个null。

  •     new Date() instanceof String

                编译不通过,因为Date类和String类没有继承或实现的关系,所以在编译时直接就报错了,instanceof操作符的左右操作数必须有继承或实现关系,否则编译失败。

  •   GenericClass<String>.isDateInstance("")

                编译不通过?不对,编译通过了,运行结果是false。T是个String类型,与Date之间没有继承或实现关系,为什么 "t instanceof Date"会编译通过呢?那是因为Java的泛型是为编码服务的,在编译成字节码时,T已经是Object类型了,传递的实参是String类型,也就是说T表面是Object ,实际类型是String ,那"t instanceof Date"这句话等价于"Object instnceof Date"了,所以返回false。


总结:

  1. instanceof只能用于对象的判断,不能用于基本类型的判断。否则会编译不通过
  2. instanceof操作符左右两个操作数必须有继承或实现关系,否则编译不通过
  3. instanceof左操作数为null时,直接返回false,不再关心右操作数的类型




暧昧贴