本文中将介绍instanceof 使用及其需要注意的事项
在Java程序设计中,instanceof是一个二元操作符,它的作用是在运行时用于判断运算符左边的对象是否为其右边类的实例(亦可以是其子类实例)。通过返回boolean值来确定.
一.如下所示
public class TestInstanceOfJava{
public static void main(String [] args){
String s="hello world";
System.out.println(s instanceof String); // 1
System.out.println(s instanceof Object); // 2
};
}
毫无疑问, 上述代码在编译后执行结果 都为true, 代码1处 s就是String的一个实例,代码2处s是Object子类的实例,所以根据定义都应该返回true。
二.继续分析如下代码
public class TestInstanceOfJava{
public static void main(String [] args){
String s="hello world";
System.out.println(s instanceof String); // 1
System.out.println(s instanceof Object); // 2
Object obj="hello";
System.out.println(obj instanceof String); // 3
System.out.println(obj instanceof Object); // 4
};
}
在这段代码中我们定义了一个obj对象,我们说instanceof ,是判断左边的对象实例在运行时阶段是否为右边对象的实例或者子类的实例.注意是运行时,在运行时obj实际指向的类型为String的实例对象,亦是Object类型子类的实例,所以上述代码在3,4处任然返回true.
三.接下来我们继续分析代码
如下
public class TestInstanceOfJava{
public static void main(String [] args){
String s="hello world";
System.out.println(s instanceof String); // 1
System.out.println(s instanceof Object); // 2
Object obj="hello";
System.out.println(obj instanceof String); // 3
System.out.println(obj instanceof Object); // 4
System.out.println(s instanceof Comparable); //5
System.out.println(obj instanceof Integer);//6
};
}
代码5处,我们知道s运行时实际指向的类型为String,String实现了Comparable接口,所以s也是Comparable接口的实例对象,所以5处返回true.
代码6处,在运行时阶段我们知道obj指向的实际类型为String类型的实例,所以它指向的实际类型并不是Integer类型的实例对象,所以6处返回false.
四.go on 我们继续
public class TestInstanceOfJava{
public static void main(String [] args){
String s="hello world";
System.out.println(s instanceof String); // 1
System.out.println(s instanceof Object); // 2
Object obj="hello";
System.out.println(obj instanceof String); // 3
System.out.println(obj instanceof Object); // 4
System.out.println(s instanceof Comparable); //5
System.out.println(obj instanceof Integer);//6
System.out.println(s instanceof Integer); //7
};
}
看看这段代码如何呢,这段代码是有问题的,不能通过编译的 7处的代码编译都通不过.编译的时候会出现如下的错误
TestInstanceOfJava.java:16: 不可转换的类型
找到: java.lang.String
需要: java.lang.Integer
System.out.println(s instanceof Integer); //7
^
1 错误
这个我们应从编译的角度考虑instanceof 运算符
在编译阶段instanceof运算符左边的操作数与右边的操作数应该满足如下关系,程序才能编译通过,否则编译错误
左边的操作数的类型要与右边操作数的类型相同(如代码1),或者左边操作数的类型是右边操作数子类类型(如代码2,代码5),或者左边操作数的类型是右边操作数父类类型(如代码3,代码6)。只有在代码编译通过的条件下通过instance的返回值才能判断。
五.最后一段代码
public class TestInstanceOfJava{
public static void main(String [] args){
String s="hello world";
System.out.println(s instanceof String); // 1
System.out.println(s instanceof Object); // 2
Object obj="hello";
System.out.println(obj instanceof String); // 3
System.out.println(obj instanceof Object); // 4
System.out.println(s instanceof Comparable); //5
System.out.println(obj instanceof Integer);//6
// System.out.println(s instanceof Integer); //7
String t=null;
System.out.println(t instanceof String);
};
}
分析这段代码8处,编译肯定通过,t的编译时类型为String与右边操作数的类型相同,虽然编译时类型相同,但是t并未实际执向一个为String类型的实例,所以这里返回false.
总结:
所以在使用instanceof的时候我们需要注意。
instanceof关键字我们可以从编译时和运行时两个方面来分析
首先在编译时应当满足上述所指出的三点关系
1. 左边的操作数的类型要与右边操作数的类型相同
2.或者左边操作数的类型是右边操作数子类类型
3.或者左边操作数的类型是右边操作数父类类型
只有通过编译时我们才能分析运行时。
在运行时阶段,当instanceof 的左操作数实际所引用的对象是第二个操作数的实例,或者是第二个操作数的子类实例(继承),实现类的实例(接口实现),结果返回true,
否则返回false 。
参考:<<Java程序员的基本修养>>
落叶飞 2015/03/13 新浪微博:@七里外风车磨坊