java: Class.isInstance vs Class.isAssignableFrom


232

Izin clazzbazı olmak Classve objbazı olmak Object.

Dır-dir

clazz.isAssignableFrom(obj.getClass())

her zaman aynı

clazz.isInstance(obj)

?

Değilse, farklılıklar nelerdir?


26
obj == null, ikincisi false değerini döndürür, ilki döndürmez. ;)
Peter Lawrey

21
@PeterLawrey, ilki bir NullPointerExceptionif atar obj == null.
ryvantage

Hrere örnekleri ile bazı cevaplar bulundu: mytechnotes.biz/2012/07/…
Paramesh Korrakuti

4
Okuyuculara: asla kaçamayacağınız derin, karanlık, kara bir deliğe girmek üzeresiniz. Farklar sonsuz. Hala yapabiliyorken vazgeç: stackoverflow.com/q/496928/1599699
Andrew

@ParameshKorrakuti alanı adı yapılacak değişiklikle tshikatshikaaa.blogspot.com/2012/07/...
Jérôme Verstrynge

Yanıtlar:


222

clazz.isAssignableFrom(Foo.class)clazznesnenin temsil ettiği sınıfın bir üst sınıfı veya üst yüzeyi olduğunda doğru olacaktır Foo.

clazz.isInstance(obj)nesne objsınıfın bir örneği olduğunda doğru olur clazz.

Yani:

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

bu kadar uzun her zaman olduğu gibi doğrudur clazzve objnonnull bulunmaktadır.


3
bu Foo'nun clazz ile aynı olduğu durumu özlüyor - bu durumda doğru dönüyor: Pauls'un aşağıda en çok oy alan yanıtı bunu düzeltir
Rhubarb

3
Clazz bir Foo olduğunda, clazz.isAssignableFrom (Foo.class) doğru olduğunu kabul ediyorum. Başka türlü nerede dedim?
uckelman

5
@Gili uckelman böyle demedi. Lütfen cevabını tekrar okuyun.
Puce

2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> arayüzler için de geçerlidir.
Puce

1
Teknik Özellikler: Eğer objbir nullsonra clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)bir atacağım NullPointerExceptionve döndürmez true.
Andrew Macheret

196

Her iki cevap da ballparkta ama ikisi de tam bir cevap değil.

MyClass.class.isInstance(obj)bir örneği kontrol etmek içindir. Obj parametresi null olmadığında ve MyClassa olmadan yükseltilebildiğinde true değerini döndürür ClassCastException. Başka bir deyişle obj, MyClassalt sınıflarının bir örneğidir .

MyClass.class.isAssignableFrom(Other.class)MyClass, ile aynı veya üst sınıf veya üst yüzey ise , true değerini döndürür Other. Otherbir sınıf veya arayüz olabilir. A Otherdönüştürülebilirse doğru yanıt verir MyClass.

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

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
Neden örneğinizde "b isAssignableFrom a:" ama kod A.class.isAssignableFrom(B.class)? Ben çıktı ile karıştı :)
Roman Truba

4
ummm ... tüm örneklerinizde "instanceOf" true iff döndürür "isAssignableFrom" true değerini döndürür ... Farkı bu şekilde görmüyorum.
android geliştirici

2
Yazdırılan metnin kodla eşleşmediğine ve kafa karıştırıcı olabileceğine dikkat edin ... Örnek: "System.out.println (" b isAssignableFrom a: "+ A.class.isAssignableFrom (B.class));"
polster

21
@Paul Cevap olduğu gibi yardımcı olmuyor, çünkü okuyucu "sınıfın bir alt sınıfının örneği olan bir nesne ile nesnenin türü sınıfa dönüştürülebilen arasındaki fark nedir?" Diye merak ediyor. Şüphesiz, cevabınızı okuduktan sonra bu sayfaya geldiğinde okuduğunuz kadar çok soru okuduğunuzu görebilirsiniz. Daha iyi bir cevap aslında farkı (veya eksikliğini) açıklar. Eğer bir fark yoksa, cevap doğrudan “pratik bir fark yoktur” şeklinde olmalıdır.
Aleksandr Dubinsky

2
Daha da önemlisi, okuyucu amaçları için ne halt kullanacağını merak ediyor. Sorudaki yorumlara göre , nesne null ise isAssignableFrom()a atar NullPointerException, oysa isInstance()sadece false döndürür. Gerçek cevap bu.
Andrew

6

Bence bu ikisinin sonucu hep aynı olmalı. Fark, kullanmak için sınıfın bir örneğine, isInstanceyalnızca kullanılacak Classnesneye ihtiyacınız olmasıdır isAssignableFrom.


Bu% 100 doğru değil. Comparable.class.isAssignableFrom(Byte.class) == trueama Byte.class.isInstance(Comparable.class) == false. Başka bir deyişle, isInstance()arayüzler için simetrik değil, sadece alt sınıflar için.
Gili

6
@Gili: Orada biraz yanlış anladın. Byte.class.isInstance(Comparable.class)bir Classnesne örneği olmadığından yanlıştır Byte. Doğru karşılaştırma Comparable.class.isAssignableFrom(Byte.class)DİR Comparable.class.isInstance((byte) 1)doğrudur.
ColinD

1
Katılmıyorum. Eğer Javadoc'a bakarsanız, Byteonu genişletir Numberve bir sınıftır. (byte) 1ile eşdeğer değil Byte. Birincisi ilkel. İkincisi bir Sınıftır.
Gili

2
@Gili: autoboxing ilkel yayınları byteiçin Bytebir parametre tipi için isInstanceolan Object.
ColinD

2
Tamam. Asıl amacım, çağrıların tam olarak simetrik olmadığı, ancak cevabınızı tekrar okuduktan sonra bu iddiayı asla yapmadınız, böylece haklısınız.
Gili

6

Kısacası, bu iki API'yı aşağıdaki gibi anlayabiliriz:

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

Eğer Xve Yaynı sınıf, ya da Xolduğu Y'ın süper sınıf veya süper arayüzü, gerçek, aksi takdirde false döndürür.

  1. X.class.isInstance(y)

Say ysınıfının bir örneğidir Yise, Xve Yaynı sınıf, ya da Xolduğu Y, aksi takdirde yanlış 'ın süper sınıf veya süper arayüzü, gerçek dönün.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.