【Java基礎】-- isAssignableFrom的用法詳細解析

[TOC]
最近在java的源代碼中老是能夠看到isAssignableFrom()這個方法,究竟是幹嗎的?怎麼用?java

1. isAssignableFrom()是幹什麼用的?

首先咱們必須知道的是,java裏面一切皆對象,類自己也是會當成對象來處理,主要體如今類的.class文件,其實加載到java虛擬機以後,也是一個對象,它就是Class對象,全限定類名:java.lang.Classc++

那這個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裏面沒有實現,那麼這個方法是幹什麼的呢?咱們從上面的註釋能夠解讀:ide

若是是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));
    }
}

運行結果以下:this

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

從運行結果來看,C繼承於BB繼承於A,那麼任何一個類均可以isAssignableFrom其自己,這個從中文意思來理解就是能夠從哪個裝換而來,自身裝換而來確定是沒有問題的,父類能夠由子類裝換而來也是沒有問題的,因此A能夠由B裝換而來,同時也能夠由子類的子類轉換而來。code

上面的代碼也說明一點,全部的類,其最頂級的父類也是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轉換而來。

這個方法在咱們平時使用的很少,可是不少源碼裏面判斷兩個類之間的關係的時候,(注意:是兩個類的關係,不是兩個類的實例對象的關係!!!),會使用到這個方法來判斷,大概由於框架代碼或者底層代碼都是通過多層抽象,作到容易拓展和解耦合,只能如此。

【做者簡介】
秦懷,公衆號【秦懷雜貨店】做者,技術之路不在一時,山高水長,縱使緩慢,馳而不息。這個世界但願一切都很快,更快,可是我但願本身能走好每一步,寫好每一篇文章,期待和大家一塊兒交流。

此文章僅表明本身(本菜鳥)學習積累記錄,或者學習筆記,若有侵權,請聯繫做者覈實刪除。人無完人,文章也同樣,文筆稚嫩,在下不才,勿噴,若是有錯誤之處,還望指出,感激涕零~

相關文章
相關標籤/搜索