设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

Java instanceof关键字详解

发布时间:2022-07-10 11:11 所属栏目:51 来源:互联网
导读:严格来说 instanceof 是 Java 中的一个双目运算符,由于它是由字母组成的,所以也是 Java 的保留关键字。在 Java 中可以使用 instanceof 关键字判断一个对象是否为一个类(或接口、抽象类、父类)的实例,语法格式如下所示。 boolean result = obj instanceo
  严格来说 instanceof 是 Java 中的一个双目运算符,由于它是由字母组成的,所以也是 Java 的保留关键字。在 Java 中可以使用 instanceof 关键字判断一个对象是否为一个类(或接口、抽象类、父类)的实例,语法格式如下所示。
  boolean result = obj instanceof Class
 
  其中,obj 是一个对象,Class 表示一个类或接口。obj 是 class 类(或接口)的实例或者子类实例时,结果 result 返回 true,否则返回 false。
 
  下面介绍 Java instanceof 关键字的几种用法。
  1)声明一个 class 类的对象,判断 obj 是否为 class 类的实例对象(很普遍的一种用法),如以下代码:
  Integer integer = new Integer(1);
  System.out.println(integer instanceof  Integer);    // true
 
  2)声明一个 class 接口实现类的对象 obj,判断 obj 是否为 class 接口实现类的实例对象,如以下代码:
  Java 集合中的 List 接口有个典型实现类 ArrayList。
  public class ArrayList<E> extends AbstractList<E>
          implements List<E>, RandomAccess, Cloneable, java.io.Serializable
 
  所以我们可以用 instanceof 运算符判断 ArrayList 类的对象是否属于 List 接口的实例,如果是返回 true,否则返回 false。
  ArrayList arrayList = new ArrayList();
  System.out.println(arrayList instanceof List);    // true
 
  或者反过来也是返回 true
  List list = new ArrayList();
  System.out.println(list instanceof ArrayList);    // true
 
  3)obj 是 class 类的直接或间接子类
  我们新建一个父类 Person.class,代码如下:
  public class Person {
  }
 
  创建 Person 的子类 Man,代码如下:
  public 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
  第 4 行代码中,Man 是 Person 的子类,Person 不是 Man 的子类,所以返回结果为 false。
 
  值得注意的是 obj 必须为引用类型,不能是基本类型。例如以下代码:
  int i = 0;
  System.out.println(i instanceof Integer);    // 编译不通过
  System.out.println(i instanceof Object);    // 编译不通过
 
  所以,instanceof 运算符只能用作对象的判断。
 
  当 obj 为 null 时,直接返回 false,因为 null 没有引用任何对象。
  Integer i = 1;
  System.out.println(i instanceof null);    // false
 
  所以,obj 的类型必须是引用类型或空类型,否则会编译错误。
 
  当 class 为 null 时,会发生编译错误,错误信息如下:
  Syntax error on token "null", invalid ReferenceType
 
  所以 class 只能是类或者接口。
 
  编译器会检查 obj 能否转换成右边的 class 类型,如果不能转换则直接报错,如果不能确定类型,则通过编译。这句话有些难理解,下面我们举例说明。
  Person p1 = new Person();
  System.out.println(p1 instanceof String);    // 编译报错
  System.out.println(p1 instanceof List);    // false
  System.out.println(p1 instanceof List<?>);    // false
  System.out.println(p1 instanceof List<Person>);    // 编译报错
  上述代码中,Person 的对象 p1 很明显不能转换为 String 对象,那么p1 instanceof String不能通过编译,但p1 instanceof List却能通过编译,而instanceof List<Person>又不能通过编译了。关于这些问题,可以查看Java语言规范Java SE8版寻找答案。
  
  可以理解成以下代码:
  boolean result;
  if (obj == null) {
      result = false;    // 当obj为null时,直接返回false
  } else {
      try {
          // 判断obj是否可以强制转换为T
          T temp = (T) obj;
          result = true;
      } catch (ClassCastException e) {
          result = false;
      }
  }
  在 T 不为 null 和 obj 不为 null 时,如果 obj 可以转换为 T 而不引发异常(ClassCastException),则该表达式值为 true ,否则值为 false 。所以对于上面提出的问题就很好理解了,p1 instanceof String会编译报错,是因为(String)p1是不能通过编译的,而(List)p1可以通过编译。
 
  instanceof 也经常和三目(条件)运算符一起使用,代码如下:
  A instanceof B ? A : C
 
  判断 A 是否可以转换为 B ,如果可以转换返回 A ,不可以转换则返回 C。下面通过一个例子来讲解,代码如下:
  public class Test {
      public Object animalCall(Animal a) {
          String tip = "这个动物不是牛!";
          // 判断参数a是不是Cow的对象
          return a instanceof Cow ? (Cow) a : tip;
      }
      public static void main(String[] args) {
          Sheep sh = new Sheep();
          Test test = new Test();
          System.out.println(test.animalCall(sh));
      }
  }
  class Animal {
  }
  class Cow extends Animal {
  }
  class Sheep extends Animal {
  }
  以上代码中,我们声明了一个 Animal 类作为父类,Cow 类和 Sheep 类为 Animal 的子类,在 Test 类的 main 函数中创建类 Sheep 的对象作为形参传递到 animalCall 方法中,因为 Sheep 类的对象不能转换为 Cow 类型,所以输出结果为“这个动物不是牛!”。

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读