Neden bir "Sınıf" değişkeni instanceof'a aktarılamıyor?


89

Bu kod neden derlenmiyor?

    public boolean isOf(Class clazz, Object obj){
        if(obj instanceof clazz){
            return true;
        }else{
            return false;
        }
    }

Neden bir sınıf değişkenine geçemiyorum instanceof?

Yanıtlar:


131

instanceofOperatör gibi başvuru türleri, üzerinde çalışır Integergibi değil, nesneler üzerinde new Integer(213). Muhtemelen şöyle bir şey istiyorsun

clazz.isInstance(obj)

Yan not: Yazarsanız kodunuz daha kısa olacaktır

public boolean isOf(Class clazz, Object obj){
    return clazz.isInstance(obj)
}

Yine de artık bir yönteme ihtiyacınız olup olmadığından emin değilim.


Kodun tamamen yararsız olduğunu biliyorum, sadece kafa karışıklığımı göstermek istiyorum :)
eric2323223

6
Integerolduğu değil , bir sınıf değişmezi. Integer.classbir sınıf değişmezi olacaktır (JLS'nin 15.8.2 maddesine bakın: java.sun.com/docs/books/jls/third_edition/html/… ). instanceofOperatör § JLS 15.20.2 belirtilen (bir tür adı olarak da bilinir), bir "ReferenceType" alır: java.sun.com/docs/books/jls/third_edition/html/...
Joachim Sauer

3
clazz.isInstance(obj)Nesne zaten sağlandığından beri kullanırım .
Donal Fellows

13

instanceofyalnızca açık sınıf isimleriyle kullanılabilir (derleme zamanında belirtilir). Bir çalışma zamanı kontrolü yapmak için şunları yapmalısınız:

clazz.isInstance(obj)

clazz.isAssignableFrom(..)Davayı obj == nulldaha iyi ele aldığı için bunun küçük bir avantajı var .


5

Başkalarının da belirttiği gibi, bir sınıf değişkenini geçiremezsiniz instanceofçünkü bir sınıf değişkeni bir Object örneğine başvururken , sağ elinin instanceofbir tür olması gerekir . Yani, instanceof"y, X Nesnesinin bir örneği" anlamına gelmez, "y, X türünün bir örneğidir" anlamına gelir. Bir Nesne ve bir tür arasındaki farkı bilmiyorsanız, şunları göz önünde bulundurun:

Object o = new Object();

Burada tür Object, ve obu türdeki Object örneğine bir referanstır. Böylece:

if(o instanceof Object)

geçerlidir ama

if(o instanceof o)

değil çünkü osağ taraftaki bir nesne değil, bir türüdür üzerinde.

Durumunuza daha özel olarak, bir sınıf örneği bir tür değildir, bir Nesnedir (sizin için JVM tarafından oluşturulur). Yönteminizde Classbir türdür, ancak clazzbir Nesnedir (bir Nesneye referans)

İhtiyacınız olan şey, bir Nesneyi bir Sınıf Nesnesi ile karşılaştırmanın bir yoludur. Bu Sınıf Nesne yöntemi olarak size verilir, böylece bu popüler olduğu ortaya çıktı: isInstance().

İşte isInstance için Java Dokümanı, bunu daha iyi açıklıyor:

public boolean isInstance(Object obj)

Belirtilen Object'in bu Sınıf tarafından temsil edilen nesneyle atama uyumlu olup olmadığını belirler. Bu yöntem, Java dili örneğinin operatörünün dinamik eşdeğeridir. Belirtilen Object bağımsız değişkeni boş değilse ve bir ClassCastException oluşturmadan bu Class nesnesi tarafından temsil edilen başvuru türüne dönüştürülebilirse yöntem true döndürür. Aksi takdirde yanlış döndürür.

Spesifik olarak, bu Class nesnesi bildirilmiş bir sınıfı temsil ediyorsa, belirtilen Object argümanı temsil edilen sınıfın (veya alt sınıflarından herhangi birinin) bir örneğiyse bu yöntem true değerini döndürür; aksi takdirde yanlış döndürür. Bu Class nesnesi bir dizi sınıfını temsil ediyorsa, belirtilen Object bağımsız değişkeni bir kimlik dönüşümü veya genişleyen bir başvuru dönüşümü ile dizi sınıfının bir nesnesine dönüştürülebiliyorsa bu yöntem true; aksi takdirde yanlış döndürür. Bu Class nesnesi bir arabirimi temsil ediyorsa, belirtilen Object bağımsız değişkeninin sınıfı veya herhangi bir üst sınıfı bu arabirimi uygularsa bu yöntem true değerini döndürür; aksi takdirde yanlış döndürür. Bu Class nesnesi bir ilkel türü temsil ediyorsa, bu yöntem false değerini döndürür.

Parametreler: obj - kontrol edilecek nesne
İade: doğru eğer obj bu sınıfın bir örneğiyse , Bu
yana: JDK1.1


3

İlk olarak, instanceofsağdaki işlenenin bir tür değişkeni değil , gerçek bir sınıf (örneğin obj instanceof Objectveya obj instanceof Integer) olmasını gerektirir Class. İkinci olarak, gerçekten yapmamanız gereken oldukça yaygın bir acemi hatası yaptınız ... aşağıdaki kalıp:

eğer ( koşullu_ifade ) {
    doğruya dön;
} Başka{
    yanlış dönüş;
}

Yukarıdakiler şu şekilde yeniden düzenlenebilir:

koşullu_ifade döndür ;

Gereksiz if ... else ifadesini ortadan kaldırdığı için her zaman bu yeniden düzenlemeyi gerçekleştirmelisiniz. Benzer şekilde, ifade aynı sonuca yeniden dönüştürülebilir.return conditional_expression ? true : false;


2
Bu bir hata değil. Belki beceriksiz ama tamam. Belki öngörülebilir gelecekte geri dönmeden önce ek kod istersiniz ...
The Incredible Jan
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.