【Javaベース】--isAssignableFromの使い方詳細解析

5760 ワード

[TOC]最近javaのソースコードではisAssignableFrom()という方法がよく見られますが、いったい何をしているのでしょうか.どう使いますか.
1.isAssignableFrom()は何に使いますか.
まず、javaの中のすべてのオブジェクトは、クラス自体もオブジェクトとして処理され、主にクラスの.classファイルに現れ、java仮想マシンにロードされた後も、オブジェクトであり、それはClassオブジェクトであり、全限定クラス名:java.lang.Classである.
では、このisAssignableFrom()はClassオブジェクトの1つの方法です.
    /**
     * 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}.
     *
     * 

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 The Java Language * Specification, 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)から継承されたかどうかを決定する場合、1つのインタフェース(A)が別のインタフェース(B)を実現したかどうか、または2つのクラスが同じであるかどうかを決定する.主に、ここで比較した次元はインスタンスオブジェクトではなく、クラス自体である.この方法自体が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

運行結果から見ると、CBに継承され、BAに継承されている.サブクラスのサブクラスから変換することもできます.
上記のコードも、すべてのクラス、その最上位の親もisAssignableFromであり、つまりすべてのタイプが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

以上の結果から,実インタフェースの実装関係とクラスの実装関係は同じであり,何の違いもないが,ObjectBが同じインタフェースを実装した場合,彼らの間では実際には互いに回転できない.
もしCがインタフェースBを実現し、ADを継承した場合、実際にBはAインタフェースに移行することができ、Dが間接的にDを実現したことに相当する.
3.まとめAは、子と親の関係を判断するために使用されるか、またはインタフェースの実装クラスとインタフェースの関係であり、デフォルトではすべてのクラスの究極の親はisAssignableFrom()である.isAssignableFrom結果がtrueである場合、ObjectA.isAssignableFrom(B)に変換できることを証明し、すなわちBAから変換できることを証明する.
この方法は普段あまり使われていませんが、多くのソースコードの中で2つのクラスの関係を判断する場合、(注意:2つのクラスの関係であり、2つのクラスのインスタンスオブジェクトの関係ではありません!!)、この方法を使って判断します.フレームワークコードや下位コードは多層抽象化されているので、和解結合が容易に広がります.そうするしかない.
【作者紹介】:秦懐、公衆号【秦懐雑貨店】作者、技術の道は一時的ではなく、山が高く水が長く、たとえゆっくりしていても、走っても止まらない.この世界はすべてが速くて、もっと速いことを望んでいますが、私は自分が一歩一歩よく歩いて、すべての文章を書いて、あなたたちと一緒に交流することを期待しています.
この文章は自分(本菜鳥)の学習蓄積記録、または学習ノートのみを代表しており、権利侵害があれば、著者に連絡して削除を確認してください.人には完璧な人がいないし、文章も同じで、文章は稚拙で、下では才能がないので、噴き出さないでください.もし間違いがあれば、指摘してください.感謝しています.