详解java中instanceof各种的用法

instanceof :
1)、类与类: 判断继承链上的实例,一般使用在强转之前的判断(多态应用时,即多态作为形参时)
2)、接口与类:接口可插拔,类都可以instanceof编译
编译看类型,运行找对象,不能通过编译
注意:final 类 不可能发生多态
已经确定的类体,指匿名子类对象
3)、接口与接口 :存在继承关系
不存在编译问题:主要看可能存在多态
代码体现:

1)String类重写Object类的equals方法(方法签名必须一致)

public boolean equals(Object anObject){     //形参是多态时,才可以使用instanceof判断,因为多态存在于继承体系中
  if(this==anObject)     //对象地址值相同直接返回真.
    return ture;
  if(anObject instanceof String){     //判断传入的实参是否为String类型,因为形参类型是固定的(重写的要求),所以需要判断
    String anotherString = (String)anObject;    //强制转换
    int n = count;
    if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
    if (v1[i++] != v2[j++])
       return false;
    }
    return true;
  }
  return false;
}

 

2)除final修饰的类及匿名子类对象外,几乎所有的类都可以通过instanceof + 接口编译(因为可能存在多态)
能否编译通过,遵循一个原则:是否可能与接口发生多态

 1 public class Test{
 2   public static void main(String[] args){
 3     B1 b1 = new B1();
 4     B1 b2 = new B2();     //多态
 5     C1 c = new C1();
 6     D1 d = new D1();
 7     D2 d2 = new D2();
 8     A a1 = new B2();
 9     System.out.println(b1 instanceof A);    //可以通过编译,因为A是可插拔的,B1的引用可以指向其子类对象,而其子类对象可能会实现了接口A(如B2),,但是运
10                             //行时就会检验了,结果为false     (B1可能与A发生多态)
11     System.out.println(b2 instanceof A);//结果为true     (B2已经与A发生多态)
12 //    System.out.println(b1 instanceof C1);    //编译失败,因为B与C之间不存在继承关系    (C1不可能与C1存在多态,没有继承关系)
13 //    System.out.println(d1 instanceof A);    //编译失败,因为D不可能有子类,不可能发生多态    (D1不可能与A多态,不可以有子类)
14     System.out.println(d2 instanceof A);    //编译通过,结果为true     (D2实现了A,与A产生了多态)
15     System.out.println(new B1() instanceof A); //B1的匿名对象,false     (B1可能与A发生多态)
16     System.out.println(new B2() instanceof A);    //B1的匿名对象,true     (B2已经与A发生多态)
17 //    System.out.println(new B1(){} instanceof A);//B1的已经确定类体的,即匿名子类对象,不能通过编译
18     System.out.println(new B2(){} instanceof A);//B2的虽未匿名子类对象,但是却属于A的实现类,所以编译通过,结果为true
19 //    System.out.println(new B3() instanceof A);    //抽象类是不可以进行实例化的,编译失败
20 //    System.out.println(new B3(){} instanceof A);//抽象类要产生匿名子类对象,必须复写所有抽象方法,编译失败
21 //    System.out.println(new B3(){public void test(){}} instanceof A);//非A的匿名子类对象,编译失败
22     System.out.println(new B4(){public void method(){}} instanceof A);//编译通过,结果为true
23   }
24 }
25 interface A{
26   void method();
27 }
28 
29 class B1{
30 
31 }
32 class B2 extends B1 implements A{
33   public void method(){}
34   }
35 abstract class B3
36 {
37   abstract void test();
38 }
39 abstract class B4 implements A
40 {
41 
42 }
43 class C1{
44 
45 }
46 final class D1
47 {
48 }
49 final class D2 implements A{
50   public void method(){}
51 }

3)接口与接口间,使用instanceof不存在编译问题,但是若使用匿名内部类则会编译失败

 1 public class Test{
 2   public static void main(String[] args){
 3   A a =new C();
 4   System.out.println(a instanceof B);    //编译通过.A可能与B发生多态,因为A的实现类有可能实现了B,结果为false
 5   System.out.println(new A(){public void test(){}} instanceof B);//编译失败,非B的匿名子类对象,不存在多态
 6   }
 7 }
 8 interface A{
 9 }
10 interface B{
11 }
12 class C implements A{
13 }

 

posted on 2013-06-15 18:53  NFC  阅读(12258)  评论(0编辑  收藏  举报

导航