java 中的instanceof 运算符研究和应用
wxleasyland@sina.com
2015.11.2
一、引用网友说的:
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
用法:
result = object instanceof class
参数:
Result:布尔类型。
Object:必选项。任意对象表达式。
Class:必选项。任意已定义的对象类。
说明:
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。
如果 object 不是指定类的一个实例,或者object 是 null,则返回 false。
二、我修改了程序:
继承形式是:
接口类A
↓
类B
|
类C← →类D
↓
类E
interface A{public void run();}
class B implements A
{ public void run(){System.out.println("B is running.");}
public void bmyself(){System.out.println("I am B.");}
public void same(){System.out.println("same B.");}
}
class C extends B //这里写不写 implements A 都可以
{ public void run(){System.out.println("C is running.");}
public void cmyself(){System.out.println("I am C.");}
public void same(){System.out.println("same C.");}
}
class D extends B implements A //这里写不写 implements A 都可以
{ public int i=0; }
class E extends C {}
class instanceoftest
{
public static B play()
{
D d=new D();
d.i=888;
return (B)d; //由于这个方法返回的类型是B类,这里是D类对象d,所以进行类型转换到B类
}
public static void main(String[] args)
{
//写new A();是错的,“A是抽象的; 无法实例化”
A aa1=new B();
aa1.run(); //得到:B is running.
A aa2=new C();
aa2.run(); //得到:C is running.
A aa3=new D();
aa3.run(); //得到:B is running.
//结论:父类中有接口类A的接口,则子类C、D中也会有接口类A的接口。 D类中是沿用了B类中的实现方法。
B bempty;
//System.out.println("anull instanceof A: " + (bempty instanceof B) ); 是错的,“尚未初始化变量bempty”
//结论:尚未初始化的变量不能使用
A anull=null;
B bnull=null;
System.out.println("anull instanceof A: " + (anull instanceof A) ); //得到false,因为对象是null
System.out.println("bnull instanceof B: " + (bnull instanceof B) ); //得到false,因为对象是null
//结论:null对象,instanceof都会返回false
A a=new B();
System.out.println("a instanceof A: " + (a instanceof A) ); //得到true
System.out.println("a instanceof B: " + (a instanceof B) ); //得到true,即子类对象赋值给父类对象的情况
System.out.println("a instanceof C: " + (a instanceof C) ); //得到false
B b=new B();
System.out.println("b instanceof A: " + (b instanceof A)); //得到true 即子类对象是父类的实例
System.out.println("b instanceof C: " + (b instanceof C)); //得到false 父类对象不是子类的实例
//结论:父类对象不是子类的实例
//结论:接口类对象就是父类对象,情况与“子类对象赋值给父类对象”相同。
C c=new C();
System.out.println("c instanceof A: " + (c instanceof A)); //得到true
System.out.println("c instanceof B: " + (c instanceof B)); //得到true 子类对象是父类的实例
//写 c instanceof D; 是错的,“不兼容的类型: C无法转换为D” 。 各子类之间无法进行实例判断
//结论:子类对象是父类的实例
E e=new E();
System.out.println("e instanceof A: " + (e instanceof A)); //得到true
System.out.println("e instanceof C: " + (e instanceof C)); //得到true
//结论:孙子类对象是爷爷类的实例
b=c; //写成b=new C();,以下结果不变
System.out.println("b instanceof C: " + (b instanceof C)); //得到true !!! 赋值后,父类对象是子类C的实例
System.out.println("b instanceof D: " + (b instanceof D)); //得到false !!! 这时,父类对象不是其它子类的实例
b.run(); //得到:C is running.
b.same(); //得到:same C. 这个居然是调用C类的方法
//写b.cmyself(); 是错的,“错误: 找不到符号”, 父类对象只能调用自已的方法
//结论:子类对象赋值给父类对象后,父类对象就按子类的来,只是不能调用子类自己的方法,并且也不能赋值给其它子类
//如何使用它:
B b_temp=play();
if ( b_temp instanceof C ) //这个是false
System.out.println("play() return instance C!!!");
if ( b_temp instanceof D ) //这个是true
{
System.out.println("play() return instance D!!!");
D d_temp=(D)b_temp; //进行类型转换
System.out.println("play() return number i="+d_temp.i);
}
//如果我们不知道play()返回到底是类C还是类D,
//如果直接 D d_temp=(D)play(); 是可以的成功的;
//但是直接 C c_temp=(C)play(); 可以编译成功,但运行就会出现异常错误!因为类型是不匹配的。
//所以必须要用这种方法区分出是C类还是D类!!
}
}
结论如下:
null对象,instanceof都会返回false
父类对象不是子类的实例,所以父类对象不能赋值给子类对象
子类对象是父类的实例,所以子类对象可以赋值给父类对象
子类对象赋值给父类对象后,父类对象就按子类的来,只是不能调用子类自己的方法,并且也不能赋值给其它子类
接口类对象就是父类对象,情况与“子类对象赋值给父类对象”相同。
三、应用
安卓的public CellLocation getCellLocation()是得到手机基站的编号,返回值类型是CellLocation类。
CellLocation是父类,子类有GsmCellLocation和CdmaCellLocation。
返回值必须转成这2个子类中的一个,才能继续用子类中的功能方法来得到基站编号。
问题是:我们事先并不知道到底返回的是哪个类。如果强制类型转换不对,安卓程序就会出错退出。
所以就需要使用instanceof运算符进行判断。
CellLocation celllocation=manager.getCellLocation();
if( celllocation == null )
{
}
else if( celllocation instanceof GsmCellLocation)
{
GsmCellLocation gsmloc = (GsmCellLocation) celllocation;
}
else if ( celllocation instanceof CdmaCellLocation)
{
CdmaCellLocation cdmaloc = (CdmaCellLocation)celllocation;
}
文章评论(0条评论)
登录后参与讨论