在之前的文章“Java:String类的使用”中,我们在String类中的String对象的比较中使用到了一个关键字——instanceof,很多人对于这个关键字还是不太理解,只知道在例子中代码是检测anObject是否是String类型的对象,这里单独写一篇文章来讲解一下。
注:本文查阅的资料主要来自GeeksforGeeks网站。
基本用法
**instanceof 是一个关键字,用于检查引用变量是否包含给定类型的对象引用。**所以,有时候我们也将其称为比较运算符。
前面文章中使用到的例子就是instanceof关键字最基本的使用方法,也是相对来说比较常用的。这里再重新举一些例子:
例1:
class A{...}
class B{...}
public class Main {
public static void main(String[] args) {
A a=new A();
if(a instanceof A){
System.out.println("yes");
}else{
System.out.println("no");
}
}
}
这是一段最简单的代码,有时候在代码量大的时候可能会用错对象,这时候加上这个条件语句能够更快找出错误的地方。
例2:
class A{...}
class B extends A{...}
public class Main {
public static void main(String[] args) {
A a=new A();
B b=new B();
if(b instanceof A){
System.out.println("yes");
}else{
System.out.println("no");
}
}
}
在更多的时候,我们使用instanceof关键字进行判断的时候,通常都是会在包含有父子类的时候使用。这时候只要记住“引用变量是否包含给定类型的对象引用”这句话即可,简单来说,其实代码的语法就是:“子类引用变量 instanceof 自己/父类及以上的对象”(及以上:表示父类的父类……),这样的运行的结果才会是true。
说到这里,引出之前的一个知识点:Object类。
因为Object类是所有类的父类,所以instanceof后面跟上的如果是Object,那么这段代码无论如何都会是true的。
instanceof关键字的应用
说完instanceof关键字的基本用法,那么instanceof关键字有什么具体的应用呢?
学到这里,应该有不少人都会说已经差不多掌握了instanceof关键字了。
class A{...}
class B extends A{...}
public class Main {
public static void main(String[] args) {
A a1=new B();
A a2=a1;
System.out.println(a2 instanceof B); //true
}
}
但是当看到这段代码,不少人的第一发应会是:false。理由很简单:instanceof后面的B对象并不是a2自己或者父类及以上的对象,不符合上面所说的,所以是false。
结果恰好相反,因为这里的情况是发生了向上转型(关于a1的那行代码其实是父类引用引用子类对象),而a1又被a2所调用,所以a2本质上是属于B类的,因此结果就是true了。
通过以上的这个例子就可以引出instanceof关键字的应用了。
class A{
public int value=100;
}
class B extends A{
public int value=10;
}
public class Main {
public static void main(String[] args) {
A a1=new B();
A a2=a1;
if(a2 instanceof B){
System.out.println("value="+((B)a2).value);
}
}
}
由于当父类引用引用子类对象(也就是向上转型)的时候,只能够访问到父类中的成员,无法访问子类的,除非发生强制类型转换(也就是向下转型),那么这时候instanceof关键字就会变得非常有用,当我们进行强制类型转换的时候,使用instanceof关键字就可以很好地检查类型转换是否有效,但判断是发生向上转型(返回true)只能访问其父类时,就可以进行强制类型转换(也就是先进行有效性检验,再进行类型转换,更加安全),这就可以比较好地处理了向下转型的缺点。
(有关向上转型和向下转型的内容可以看看之前的文章:Java:继承和多态)