Java中的instanceof运算符

时间:2020-01-09 10:34:47  来源:igfitidea点击:

Java中的instanceof运算符用于在运行时测试对象的类型。

Java instanceof运算符的语法如下:

objRef instanceof objType

这里objRef是对实例的引用。
objType表示类类型。

使用instanceof运算符,我们可以检查objRef是否为objType类型。如果是,则instanceof运算符返回true,否则返回false。

在Java中使用instanceof运算符

instanceof运算符可以帮助防止在运行时ClassCastException。

例如,父类引用可以引用子类,而相反,子类引用父类会导致编译时错误而没有类型转换。

Child c = new Parent(); // Compile time error

// Ok with downcasting, may result in ClassCastException
Child c = (Child) new Parent();

如果有多个子级并且我们在不知道实际类型的情况下进行转换,则此向下转换(父级到子级)将导致ClassCastException。以下Java示例显示了此场景,其中有两个子类Child和AnotherChild。在methodToCast方法中,即使传递AnotherChild引用导致ClassCastException,我们仍尝试将其强制转换为Child。

public class Test {
  public static void main(String[] args) {
    Child c = new Child();
    Parent p = new Parent();
    AnotherChild ac = new AnotherChild();
    // ok, upcasting to parent reference
    p = c;
    methodToCast(c);
    methodToCast(ac);
  }
	
  private static void methodToCast(Parent p) {
    Child c = (Child)p;
  }	
}

class Parent {
  public void method1() {
    System.out.println("In method");
  }
}

class Child extends Parent {
  public void method1() {
    System.out.println("In child method");
  }
}

class AnotherChild extends Parent {
  public void method1() {
    System.out.println("In Anotherchild method");
  }
}

输出:

Exception in thread "main" java.lang.ClassCastException: com.theitroad.programs.AnotherChild cannot be cast to com.theitroad.programs.Child
	at com.theitroad.programs.Test.methodToCast(Test.java:15)
	at com.theitroad.programs.Test.main(Test.java:11)

在这种情况下,我们需要使用instanceof运算符来检查引用的类型。

private static void methodToCast(Parent p) {
	if(p instanceof Child) {
		Child c = (Child)p;
	}
}

考虑具有多级继承的另一种情况。

public class Test {
	public static void main(String[] args) {
		Parent p = new Parent();
		Child c = new Child();
		AnotherChild ac = new AnotherChild();
		GrandChild gc = new GrandChild();
		methodToCast(c);
		methodToCast(gc);
		methodToCast(ac);
	}
	
	private static void methodToCast(Parent p) {
		Child c = (Child)p;
		c.method1();
	}
	
}

class Parent {
	public void method1() {
		System.out.println("In Parent method");
	}
}

class Child extends Parent {
	public void method1() {
		System.out.println("In Child method");
	}
}

class AnotherChild extends Parent {
	public void method1() {
		System.out.println("In Anotherchild method");
	}
}

class GrandChild extends Child {
	public void method1() {
		System.out.println("In GrandChild method");
	}
}

输出:

In Child method
In GrandChild method
Exception in thread "main" java.lang.ClassCastException: com.theitroad.programs.AnotherChild cannot be cast to com.theitroad.programs.Child
	at com.theitroad.programs.Test.methodToCast(Test.java:15)
	at com.theitroad.programs.Test.main(Test.java:11)

如我们所见,铸造为Child和GrandChild(也属于Child类型)而进行,但是对ParentChild类型为ParentChild抛出ClassCastException。在这种情况下,使用instanceof运算符检查类型可确保仅针对子类型引用调用该方法。

private static void methodToCast(Parent p) {
	if(p instanceof Child) {
		Child c = (Child)p;
		c.method1();
	}
}

关于Java中的instanceof运算符的要点

1如果对象引用为null,instanceof运算符将返回false。

public class Test {
	public static void main(String[] args) {
		Test obj = null;
		if(obj instanceof Test) {
			System.out.println("instance of operator returns true");
		}else {
			System.out.println("instance of operator returns false");
		}
	}
}

输出:

instance of operator returns false

2使用Object类的instanceof运算符进行测试始终返回true,因为Object类是Java中所有类的超类。

public class Test {
  public static void main(String[] args) {
    Test obj = new Test();
    Parent p = new Parent();
    if(obj instanceof Object) {
      System.out.println("instance of operator returns true");
    }else {
      System.out.println("instance of operator returns false");
    }
    
    if(p instanceof Object) {
      System.out.println("instance of operator returns true");
    }else {
      System.out.println("instance of operator returns false");
    }
  }
}

class Parent {
  public void method1() {
    System.out.println("In Parent method");
  }
}

输出:

instance of operator returns true
instance of operator returns true