• java isAssignableFrom()


     

    1. isAssignableFrom()是干什么用的?

    首先我们必须知道的是,java里面一切皆对象,类本身也是会当成对象来处理,主要体现在类的.class文件,其实加载到java虚拟机之后,也是一个对象,它就是Class对象,全限定类名:java.lang.Class

    那这个isAssignableFrom()其实就是Class对象的一个方法:

    /**
         * Determines if the class or interface represented by this
         * {@code Class} object is either the same as, or is a superclass or
         * superinterface of, the class or interface represented by the specified
         * {@code Class} parameter. It returns {@code true} if so;
         * otherwise it returns {@code false}. If this {@code Class}
         * object represents a primitive type, this method returns
         * {@code true} if the specified {@code Class} parameter is
         * exactly this {@code Class} object; otherwise it returns
         * {@code false}.
         *
         * <p> Specifically, this method tests whether the type represented by the
         * specified {@code Class} parameter can be converted to the type
         * represented by this {@code Class} object via an identity conversion
         * or via a widening reference conversion. See <em>The Java Language
         * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
         *
         * @param cls the {@code Class} object to be checked
         * @return the {@code boolean} value indicating whether objects of the
         * type {@code cls} can be assigned to objects of this class
         * @exception NullPointerException if the specified Class parameter is
         *            null.
         * @since JDK1.1
         */
        public native boolean isAssignableFrom(Class<?> cls);
    

    native关键字描述,说明是一个底层方法,实际上是使用c/c++实现的,java里面没有实现,那么这个方法是干什么的呢?我们从上面的注释可以解读:

    如果是A.isAssignableFrom(B) 确定一个类(B)是不是继承来自于另一个父类(A),一个接口(A)是不是实现了另外一个接口(B),或者两个类相同。主要,这里比较的维度不是实例对象,而是类本身,因为这个方法本身就是Class类的方法,判断的肯定是和类信息相关的。

    也就是判断当前的Class对象所表示的类,是不是参数中传递的Class对象所表示的类的父类,超接口,或者是相同的类型。是则返回true,否则返回false。

    2.代码实验测试

    2.1 父子继承关系测试

    class A{
    }
    class B extends A{
    }
    class C extends B{
    }
    public class test {
        public static void main(String[] args) {
            A a = new A();
            B b = new B();
            B b1 = new B();
            C c = new C();
            System.out.println(a.getClass().isAssignableFrom(a.getClass()));
            System.out.println(a.getClass().isAssignableFrom(b.getClass()));
            System.out.println(a.getClass().isAssignableFrom(c.getClass()));
            System.out.println(b1.getClass().isAssignableFrom(b.getClass()));
    
            System.out.println(b.getClass().isAssignableFrom(c.getClass()));
    
            System.out.println("=====================================");
            System.out.println(A.class.isAssignableFrom(a.getClass()));
            System.out.println(A.class.isAssignableFrom(b.getClass()));
            System.out.println(A.class.isAssignableFrom(c.getClass()));
    
            System.out.println("=====================================");
            System.out.println(Object.class.isAssignableFrom(a.getClass()));
            System.out.println(Object.class.isAssignableFrom(String.class));
            System.out.println(String.class.isAssignableFrom(Object.class));
        }
    }
    

    运行结果如下:

    true
    true
    true
    true
    true
    =====================================
    true
    true
    true
    =====================================
    true
    true
    false
    

    从运行结果来看,C继承于BB继承于A,那么任何一个类都可以isAssignableFrom其本身,这个从中文意思来理解就是可以从哪一个装换而来,自身装换而来肯定是没有问题的,父类可以由子类装换而来也是没有问题的,所以A可以由B装换而来,同时也可以由子类的子类转换而来。

    上面的代码也说明一点,所有的类,其最顶级的父类也是Object,也就是所有的类型都可以转换成为Object

    2.2 接口的实现关系测试

    interface InterfaceA{
    }
    
    class ClassB implements InterfaceA{
    
    }
    class ClassC implements InterfaceA{
    
    }
    class ClassD extends ClassB{
    
    }
    public class InterfaceTest {
        public static void main(String[] args) {
            System.out.println(InterfaceA.class.isAssignableFrom(InterfaceA.class));
            System.out.println(InterfaceA.class.isAssignableFrom(ClassB.class));
            System.out.println(InterfaceA.class.isAssignableFrom(ClassC.class));
            System.out.println(ClassB.class.isAssignableFrom(ClassC.class));
            System.out.println("============================================");
    
            System.out.println(ClassB.class.isAssignableFrom(ClassD.class));
            System.out.println(InterfaceA.class.isAssignableFrom(ClassD.class));
        }
    }
    

    输出结果如下:

    true
    true
    true
    false
    ============================================
    true
    true
    

    从上面的结果看,其实接口的实现关系和类的实现关系是一样的,没有什么区别,但是如果BC都实现了同一个接口,他们之间其实是不能互转的。

    如果B实现了接口AD继承了B,实际上D是可以上转为A接口的,相当于D间接实现了A,这里也说明了一点,其实继承关系和接口实现关系,在isAssignableFrom()的时候是一样的,一视同仁的。

    3.总结

    isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的,默认所有的类的终极父类都是Object。如果A.isAssignableFrom(B)结果是true,证明B可以转换成为A,也就是A可以由B转换而来。

    这个方法在我们平时使用的不多,但是很多源码里面判断两个类之间的关系的时候,(注意:是两个类的关系,不是两个类的实例对象的关系!!!),会使用到这个方法来判断,大概因为框架代码或者底层代码都是经过多层抽象,做到容易拓展和解耦合,只能如此。

    转载:https://zhuanlan.zhihu.com/p/317784108

  • 相关阅读:
    数学角度看设计模式之观察者模式
    XML、JSON数据结构解析
    [理解ASP.NET Core框架]一个五十行的控制台Web
    .Net Core 学习 (1)
    SqlServer windowss身份登陆和sa身份登陆
    学习51单片机——秒表分享
    C语言中函数声明实现的位置
    java DOM4J 读取XML
    服务器与Linux操作系统基础原理
    Go语言实现数据结构(一)单链表
  • 原文地址:https://www.cnblogs.com/xiaohouye/p/16249936.html
Copyright © 2020-2023  润新知