Nesnenin arayüzü uygulayıp uygulamadığını test edin


149

Bu muhtemelen daha önce sorulmuştur, ancak hızlı bir arama sadece C # için aynı soruyu gündeme getirdi. Buraya bakın.

Temelde yapmak istediğim, belirli bir nesnenin belirli bir arabirimi uygulayıp uygulamadığını kontrol etmektir.

Ben bir çözüm anladım ama bu sadece veya durum ifadelerinde sık kullanmak için yeterince rahat değil ve Java yerleşik bir çözüm olup olmadığını merak ediyordum.

public static Boolean implementsInterface(Object object, Class interf){
    for (Class c : object.getClass().getInterfaces()) {
        if (c.equals(interf)) {
            return true;
        }
    }
    return false;
}


EDIT: Tamam, cevaplarınız için teşekkürler. Özellikle Damien Pollet ve Noldorin için, tasarımımı yeniden düşünmemi sağladın, böylece artık arayüzleri test etmiyorum.


3
Biri atılırsa (ve Java'nın C # "operatörüne" benzer bir şey varsa bile boş bir sonuç olup olmadığını kontrol ederseniz) döküm yapmayı ve istisnayı yakalayamaz mısınız? Ben bir Java yerine bir C # kodlayıcı, bu yüzden ben esas olarak burada tahmin ediyorum, ancak herhangi bir OO dilinde böyle bir yaklaşım mümkün olacağını düşünürdüm.
Noldorin

1
Bu durumda, yalnızca performansı önemsemeniz gerekmiyorsa, istisna atmak iyi bir uygulamadır.
Rafa

1
Affedersiniz ama bu cevaplar tasarımınızı yeniden düşünmenize neden oldu? Silmiş olsalar bile, onlar neydi? Bana yardım edebilir misiniz
@sebastiangeiger

1
@ozanmuyes Üzgünüm, 4 yıldan fazla bir süredir Java yazmadım ve ne yazık ki ne yaptığımı hatırlayamıyorum.
sebastiangeiger

Yanıtlar:


191

instanceofOperatör bir iş yapar NullPointerExceptiongüvenli bir şekilde. Örneğin:

 if ("" instanceof java.io.Serializable) {
     // it's true
 }

gerçek verir. Dan beri:

 if (null instanceof AnyType) {
     // never reached
 }

false instanceofdeğerini verirse , operatör null güvenlidir (postaladığınız kod değil).

instanceof , Class # isInstance (Object) öğesine yerleşik, derleme zamanı güvenli bir alternatiftir


5
instanceof sadece sınıf değişmezleri üzerinde çalışır. Bu yüzden OP davasında kullanılamaz
LordOfThePigs

emin, derleme zamanı güvenlidir; ve bu yerleşik yoldur ve sorunun argümanıdır (imho)
dfa

@LordOfThePigs hayır değil. Bir arabirimin de uygulanıp uygulanmadığını kontrol eder.
NimChimpsky

5
@NimChimpsky: fikrimi yanlış anladın. Sınıf değişmezleri, kaynak kodunuzda MyClass.classveya MyInterface.classkaynak kodunuzda yazdığınız zamandır . Sınıf değişmezleri sınıflara, arabirimlere ve ilkel türlere atıfta bulunabilir ve karşılık gelen bir örneği Class sınıfına döndürür. Demek istediğim, OP bir sınıf değişmezi kullanmıyor, bunun yerine Class sınıfının bir örneğidir ve maalesef instanceofanahtar kelimenin sağ taraftaki işlecinin Class sınıfının bir örneği değil, bir sınıf değişmezi olması gerekir.
LordOfThePigs

@ dsdsdsdsd Bu yazımdan bu yana bile duymadım / okumadım, ancak Google'a baktıktan sonra Null Pointer Exception'ın kısaltması olduğunu anladım.
ozanmuyes

42

Bu şunları yapmalıdır:

public static boolean implementsInterface(Object object, Class interf){
    return interf.isInstance(object);
}

Örneğin,

 java.io.Serializable.class.isInstance("a test string")

olarak değerlendirir true.


8

Ben tercih ederim instanceof:

if (obj instanceof SomeType) { ... }

daha yaygın ve okunabilir olan SomeType.isInstance(obj)


5
Bunun if (obj instanceof SomeType) { ... }statik (yani çalışma zamanında değişemeyeceğini) ve SomeType.isInstance(obj)dinamik olduğunu unutmayın.
Tomasz Bielaszewski


3

Arayüzleri test etmek istiyorsanız:

public List<myType> getElement(Class<?> clazz) {
    List<myType> els = new ArrayList<myType>();
    for (myType e: this.elements.values()) {
        if (clazz.isAssignableFrom(e.getClass())) {
            els.add(e);
        }
    }
    return els;

}

clazz bir Arayüz ve myType, tanımladığınız ve bir takım arayüzler uygulayabilecek bir Tür. Bu kodla, yalnızca tanımlı bir arabirimi uygulayan türleri alırsınız


1

Bu gece android ile bu sorunu yaşadım ve javadoc çözümlerine baktıktan sonra, benim gibi bir javadoc açıklamasından biraz daha fazlasına ihtiyaç duyan insanlar için bu gerçek çalışma çözümünü buldum.

İşte android java kullanarak gerçek bir arayüze sahip çalışan bir örnek. AboutDialogListener alanını yayınlamaya çalışmadan önce, AboutDialogListener arabirimini uygulanmış olarak adlandırılan etkinliği denetler.

public class About extends DialogFragment implements OnClickListener,
    OnCheckedChangeListener {

public static final String FIRST_RUN_ABOUT = "com.gosylvester.bestrides.firstrunabout";


public interface AboutDialogListener {
    void onFinishEditDialog(Boolean _Checked);
}

private AboutDialogListener adl;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Activity a = this.getActivity();
    if (AboutDialogListener.class.isInstance(a)) {
        adl = (AboutDialogListener) a;
        }
}

... Daha sonra arayüzü çağırmadan önce alan adl! Null olup olmadığını kontrol edin

@Override
public void onStop() {
    super.onStop();
    sharedPref.edit().putBoolean(About.FIRST_RUN_ABOUT, _Checked).commit();
    // if there is an interface call it.
    if (adl != null) {
        adl.onFinishEditDialog(is_Checked());
    }
}

0

Apache commons-lang ArrayUtils ile, ihtiyacınız olan arabirimin nesnenizin arabirimlerinde bulunup bulunmadığına bakın

public static Boolean implementsInterface(Object object, Class interf){
    return ArrayUtils.contains(object.getClass().getInterfaces(), interf);
}
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.