zoukankan      html  css  js  c++  java
  • 详解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 }
  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/withyou/p/3137885.html
Copyright © 2011-2022 走看看