java:Class.isInstanceとClass.isAssignableFrom


232

ましょうclazz、いくつかのことClassobj、いくつかのことObject

です

clazz.isAssignableFrom(obj.getClass())

常に同じ

clazz.isInstance(obj)

そうでない場合、違いは何ですか?


26
obj == nullの場合、2番目はfalseを返し、1番目はそうではありません。;)
Peter Lawrey

21
@PeterLawrey、最初はNullPointerExceptionif をスローしますobj == null
ryvantage 2014年

ハリアからのサンプルであるいくつかの答え:mytechnotes.biz/2012/07/...
Paramesh Korrakuti

4
読者へ:あなたは、あなたが決して逃げることのできない、深くて暗い黒い穴に入りそうです。違いは無限です。まだできる間は諦めてください:stackoverflow.com/q/496928/1599699
Andrew

@ParameshKorrakutiドメイン名がに変化しているtshikatshikaaa.blogspot.com/2012/07/...
ジェローム・Verstrynge

回答:


222

clazz.isAssignableFrom(Foo.class)clazzオブジェクトによって表されるクラスがのスーパークラスまたはスーパーインターフェースである場合は常にtrueになりますFoo

clazz.isInstance(obj)オブジェクトobjがクラスのインスタンスである場合は常にtrueになりますclazz

あれは:

clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)

限り、常に真であるclazzobj非NULLです。


3
これは、Fooがclazzと同じである場合を逃します-その場合、それはtrueを返します:Paulsのトップ投票の回答がこれを修正します
Rhubarb

3
clazzがFooの場合、clazz.isAssignableFrom(Foo.class)がtrueであることに同意します。他にどこに言ったの?
uckelman 2013

5
@Giliこれはuckelmanが言ったことではありません。彼の答えをもう一度読んでください。
Puce、2014

2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); ->インターフェースについても同様です。
Puce、2014

1
専門的事項:場合objnull、その後clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)スローされますNullPointerExceptionと戻りませんtrue
Andrew Macheret

196

どちらの回答も大枠内にありますが、どちらも完全な回答ではありません。

MyClass.class.isInstance(obj)インスタンスをチェックするためのものです。パラメータobjがnullでMyClassなく、を発生させずにキャストできる場合、trueを返しますClassCastException。つまり、objは、MyClassまたはそのサブクラスのインスタンスです。

MyClass.class.isAssignableFrom(Other.class)がとMyClass同じ、またはそのスーパークラスまたはスーパーインターフェースである場合にtrueを返しますOtherOtherクラスまたはインターフェースにすることができます。にOther変換できる場合はtrueを返しますMyClass

デモンストレーションする小さなコード:

public class NewMain
{
    public static void main(String[] args)
    {
        NewMain nm = new NewMain();
        nm.doit();
    }

    class A { }

    class B extends A { }

    public void doit()
    {
        A myA = new A();
        B myB = new B();
        A[] aArr = new A[0];
        B[] bArr = new B[0];

        System.out.println("b instanceof a: " + (myB instanceof A)); // true
        System.out.println("b isInstance a: " + A.class.isInstance(myB)); //true
        System.out.println("a isInstance b: " + B.class.isInstance(myA)); //false
        System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class)); //true
        System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class)); //false
        System.out.println("bArr isInstance A: " + A.class.isInstance(bArr)); //false
        System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr)); //true
        System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass())); //true
    }
}

10
なぜあなたの例では "b isAssignableFrom a:"ですが、コードはA.class.isAssignableFrom(B.class)?出力で混乱しました:)
Roman Truba 2014年

4
うーん...すべての例で、「instanceOf」はtrueを返しますが、「isAssignableFrom」はtrueを返します...このように違いがわかりません。
Android開発者

2
印刷されたテキストがコードと一致せず、混乱を招く可能性があるので注意してください...例: "System.out.println(" b isAssignableFrom a: "+ A.class.isAssignableFrom(B.class));"
polster 2015

21
@Paul答えはそのままでは役に立ちません。読者が「クラスのサブクラスのインスタンスであるオブジェクトとクラスに変換可能なオブジェクトの型の違いは何ですか?」確かに、読者がこのページにたどり着いたときと同じように、あなたの回答を読んだ後、あなたは読者に多くの質問を残したことがわかります。より良い答えは実際に違い(またはその欠如)を説明するでしょう。違いがない場合、答えは「実際的な違いはない」と直接述べる必要があります。
Aleksandr Dubinsky 2016

2
さらに重要なのは、読者は何のために何を使うのか不思議に思うことです。質問のコメントによると、オブジェクトがnullの場合はをisAssignableFrom()スローNullPointerExceptionしますが、isInstance()falseを返すだけです。それが本当の答えです。
Andrew

6

これら2つの結果は常に同じであると思います。違いは、使用するクラスのインスタンスが必要であり、使用isInstanceするClassオブジェクトだけであるということisAssignableFromです。


これは100%真実ではありません。Comparable.class.isAssignableFrom(Byte.class) == trueしかしByte.class.isInstance(Comparable.class) == false。言い換えれば、isInstance()はインターフェースに対して対称ではなく、サブクラスに対してのみです。
ギリ14

6
@ジリ:少し間違っているよ。オブジェクトはのインスタンスではないByte.class.isInstance(Comparable.class)ため、はfalse ClassですByte。正しい比較がComparable.class.isAssignableFrom(Byte.class)あるComparable.class.isInstance((byte) 1)真です、。
ColinD 2014

1
同意しません。ByteあなたがJavadocを調べるNumberと、それが拡張され、クラスであることがわかります。(byte) 1はと同等ではありませんByte。前者はプリミティブです。後者はクラスです。
ギリ14

2
@Gili:オートボクシングプリミティブキャストbyteByteのパラメータの型があるためisInstanceですObject
ColinD 2014

2
はい。私の最初のポイントは、呼び出しが互いに正確に対称的ではないということでしたが、あなたの答えをもう一度読んだので、あなたはこの主張をしたことがないので、あなたは正しいです。
Gili

6

簡潔にするために、以下の2つのAPIを理解できます。

  1. X.class.isAssignableFrom(Y.class)

場合XY同じクラスで、またはXであるYのは、スーパークラスやスーパーインタフェース、falseを、そうでない場合は、trueを返します。

  1. X.class.isInstance(y)

セイは、yクラスのインスタンスであるY場合、XおよびY同じクラスで、またはXであるY、そうでない場合は、偽のスーパークラスやスーパーインタフェースは、trueを返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.