原创 java 中的instanceof 运算符研究和应用

2015-11-7 09:20 1213 18 18 分类: 软件与OS 文集: 学以致用

 

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条评论)

登录后参与讨论
我要评论
0
18
关闭 站长推荐上一条 /2 下一条