Soru java: Class.isInstance ve Class.isAssignableFrom


let clazz biraz olsun Class ve obj biraz olsun Object.

clazz.isAssignableFrom(obj.getClass())

her zaman aynı

clazz.isInstance(obj)

?

Değilse, farklılıklar nelerdir?


189
2017-10-16 14:24


Menşei


eğer obj == null ise, ikinci false değerini döndürür, ilki değil. ;) - Peter Lawrey
@PeterLawrey, ilk bir atar NullPointerException Eğer obj == null. - ryvantage
Hrere'den örnekler ile bazı cevaplar buldum: mytechnotes.biz/2012/07/... - Paramesh Korrakuti
Okuyuculara: asla kaçmayacağınız koyu, karanlık bir kara deliğe girmek üzeresiniz. Farklılıklar sonsuzdur. Hala yapabiliyorken şu andan vazgeç: stackoverflow.com/q/496928/1599699 - Andrew


Cevaplar:


clazz.isAssignableFrom(Foo.class) Sınıf tarafından temsil edilen sınıf her zaman doğru olacaktır. clazz nesne bir süper sınıfı veya süper bir Foo.

clazz.isInstance(obj) nesne ne zaman doğru olacak obj sınıfın bir örneğidir clazz.

Yani:

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

her zaman olduğu kadar doğru clazz ve obj nonnull.


164
2017-10-16 14:55



Bu, Foo'nun clazz ile aynı olduğu durumu özlüyor - bu durumda, gerçekte geri dönüyor: Paul'un üstteki yanıtı bunu düzeltiyor - Rhubarb
Clazz bir Foo olduğunda, o zaman clazz.isAssignableFrom (Foo.class) doğru olduğunu kabul ediyorum. Aksini nasıl söyledim? - uckelman
@Gili Bu, uckelman'ın söylediği şey değil. Lütfen cevabını tekrar oku. - Puce
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));  -> arayüzler için de geçerlidir. - Puce
@Puce Tamamen haklısınız. Benim hatam! - Gili


Her iki cevap da basketbol sahasında, ama tam bir cevap değil.

MyClass.class.isInstance(obj) bir örneği kontrol etmek içindir. Obj, null değerindeyken true değerine döner ve MyClass yükseltmeden ClassCastException. Başka bir deyişle, obj bir örneğidir. MyClass veya alt sınıfları.

MyClass.class.isAssignableFrom(Other.class) doğruysa döner MyClass bir süper sınıfı veya süper bir yüzü ile aynıdır, Other. Other bir sınıf veya bir arayüz olabilir. Eğer doğru cevaplarsa Other bir dönüştürülebilir MyClass.

Göstermek için küçük bir kod:

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

    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));
        System.out.println("b isInstance a: " + A.class.isInstance(myB));
        System.out.println("a isInstance b: " + B.class.isInstance(myA));
        System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class));
        System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class));
        System.out.println("bArr isInstance A: " + A.class.isInstance(bArr));
        System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr));
        System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass()));
    }

    class A
    {
    }

    class B extends A
    {
    }
}

Ve çıktı:

b instanceof a: true
b isInstance a: true
a isInstance b: false
b isAssignableFrom a: true
a isAssignableFrom b: false
bArr isInstance A: false
bArr isInstance aArr: true
bArr isAssignableFrom aArr: true

173
2017-08-08 14:23



Her ikisi de 3. ve sondan sonuncu hatlara bArr isInstance aArr ama kod farklı. - Brad Cupit
Örneğinizde neden "b isAssignableFrom a:" ancak kod A.class.isAssignableFrom(B.class)? Çıktı ile karıştırdım :) - Roman Truba
ummm ... tüm örneklerinizdeki "instanceOf" ifadesi true iff "isAssignableFrom" döndürür true ... Bu şekilde farkı göremiyorum. - android developer
Yazdırılan metnin kodla uyuşmadığından emin olun ve kafa karıştırıcı olabilir ... Örnek: "System.out.println (" b isAssignableFrom a: "+ A.class.isAssignableFrom (B.class));" - polster
@Paul Cevap, yararlı değildir, çünkü okuyucu “bir nesnenin bir sınıfın bir alt sınıfının örneği ve nesnenin türü sınıfa dönüştürülebilen bir şey arasındaki fark nedir?” Diye merak etmekten vazgeçtiği için. Şüphesiz, okuyucuyu bu sayfaya geldiğinde cevabınızı okuduktan sonra birçok soruyla birlikte bıraktığınızı görebilirsiniz. Daha iyi bir cevap aslında farkı (ya da eksikliğini) açıklayacaktır. Fark yoksa, cevap doğrudan “pratik bir fark yoktur” demelidir. - Aleksandr Dubinsky


Bence bu ikisinin sonucu her zaman aynı olmalı. Fark, kullanmak için sınıfın bir örneğine ihtiyacınız olmasıdır. isInstance ama sadece Class kullanılacak nesne isAssignableFrom.


4
2017-10-16 14:26



Bu% 100 doğru değil. Comparable.class.isAssignableFrom(Byte.class) == true fakat Byte.class.isInstance(Comparable.class) == false. Diğer bir deyişle, isInstance() sadece alt sınıflar için arayüzler için simetrik değildir. - Gili
@Gili: Orada biraz yanlış var. Byte.class.isInstance(Comparable.class) yanlış çünkü Class nesne bir örneği değil Byte. Doğru karşılaştırma Comparable.class.isAssignableFrom(Byte.class) olduğu Comparable.class.isInstance((byte) 1), hangisi doğru. - ColinD
Katılmıyorum. Eğer Javadoc'a bakarsanız Byte keşfettiğini keşfedeceksiniz Number ve bir sınıftır. (byte) 1 eşdeğer değildir Byte. İlki bir ilkeldir. İkincisi bir sınıftır. - Gili
@Gili: Autoboxing ilkel atıyor byte için Byte çünkü parametre türü isInstance olduğu Object. - ColinD
Tamam. Asıl amacım çağrıların birbiriyle tam olarak simetrik olmamasıydı, fakat cevabınızı tekrar okuyarak bu iddiayı asla yapmadınız, bu yüzden haklısınız. - Gili


Kısıtlama için, aşağıdaki gibi bu iki API'yi anlayabiliriz:

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

X ve Y aynı sınıfsa veya X, Y'nin süper sınıfı veya süper arabirimiyse, aksi halde false değerini döndürür.

  1. X.class.isInstance (y):

Y'nin, X ve Y aynı sınıfsa ya da X'in Y'nin süper sınıfı veya süper arayüzü ise, Y, doğru bir şekilde, aksi halde yanlış olarak döndüğünü söyleyin.


4
2017-08-01 06:57