instanceof运算符的前一个操作数是一个引用类型变量,后一个操作数是一个类(接口),用于判断前面的对象是否是后面的类,或子类、实现类的实例。若是,返回true;反之,返回false。
instanceof运算符前面的操作数编译时的类型要么与后面的类型相同,要么与后面的类型有父子继承关系,否则会引起编译错误。
public class InstanceofTest
{
public static void main(String[] args)
{
//声明o的时候使用的Object类,则o编译时的类型是Object
//Object类是所有类的父类,但o的实际类型是String
Object o = "hello";
//String类是Object的子类,可以进行instanceof运算,返回true
System.out.println("字符串是否是Object类的实例" + (o instanceof Object));
//返回true
System.out.println("字符串是否是String的类实例" + (o instanceof String));
//Math类是Object的子类,可以进行instanceof运算,返回false
System.out.println("字符串是否是Math类的实例" + (o intstanceof Math));
//String类实现了Comparable接口,可以进行instanceof运算,返回true
System.out.println("字符串是否是Comparable接口的实例" + (o instanceof Comparable));
String s = "hello";
//String类既不是Math类,也不是Math类的父类,编译无法通过
System.out.println("字符串是否是Math类的实例" + (s instanceof Math));
}
}
基本类型之间的强制类型转换只能在数值类型之间进行,数值类型和布尔类型之间不能进行转换。
引用类型之间的强制转换只能在具有继承关系的两个类型之间进行。两个没有继承关系的类型进行强制转换会发生编译错误。如果试图把一个父类实例转换成子类类型,则这个对象必须实际上是子类实例(即编译时类型为父类类型,运行时类型为子类类型),否则将会在运行时引发ClassCastException异常。
所以可以通过使用instanceof运算符判定两个类型是否具有继承关系,从而避免出现异常。
//os编译时为Object类,实际上是String类,向上转型,自动完成
Object os = "hello";
if(os instanceof String)//ture
{
String s = (String)os;//语句执行,向下转型,强制完成
}
//oi编译时为Object类,实际上是Integer类
Object oi = new Integer(5);
if(oi instanceof String)//false
{
String s = (String)oi;//语句不执行
}
String s = "hello";
if(s instanceof Integer)//编译错误,操作数无继承关系
{
Integer i = (Integer)s;
}