2009-04-19 12 views
121

Prawdopodobnie zostało to wcześniej zadane, ale szybkie wyszukiwanie wywoływało tylko to samo pytanie, które zadano dla C#. See here.Sprawdź, czy obiekt implementuje interfejs

Co zasadniczo chcę zrobić, to sprawdzić, czy dany obiekt implementuje dany interfejs.

W pewnym sensie znalazłem rozwiązanie, ale nie jest to po prostu wystarczająco wygodne, aby często go używać w instrukcjach if i case i zastanawiałem się, czy Java nie ma wbudowanego rozwiązania.

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


EDIT: Ok, dzięki za odpowiedzi. Zwłaszcza dla Damiena Polleta i Noldorina, zmusiłeś mnie do przemyślenia mojego projektu, więc nie testuję już interfejsów.

+3

Nie możesz po prostu spróbować odlewania i złapać wyjątek, jeśli ktoś jest wyrzucany (lub sprawdzić wynik zerowy nawet, jeśli Java ma coś analagicznego do operatora C# "as")? Jestem programistą C#, a nie Java, więc domyślam się, że takie podejście byłoby możliwe w każdym języku OO. – Noldorin

+0

yay! serdecznie zapraszamy :) –

+0

Wyjątek wyrzucania jest dobrą praktyką w tym przypadku, tylko jeśli nie musisz przejmować się wydajnością. – Rafa

Odpowiedz

159

Operator instanceof działa w NullPointerException bezpieczny sposób. Na przykład:

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

daje wartość true. Od:

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

daje fałszywy, operator instanceof jest null sejf (kod zostanie zaksięgowana nie jest).

instanceof jest wbudowany, w czasie kompilacji bezpieczna alternatywa dla Class#isInstance(Object)

+4

instanceof działa tylko na literałach klasowych. Więc nie może być użyty w przypadku OP – LordOfThePigs

+0

z pewnością jest to czas kompilacji; i jest wbudowany sposób i jest argumentem pytania (imho) – dfa

+0

@LordOfThePigs no it does not. Sprawdza, czy interfejs jest zaimplementowany. – NimChimpsky

40

ten powinien zrobić:

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

Na przykład

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

ocenia się true.

+1

+1 to - nie zawiedzie, jeśli obiekt ma wartość null – msangel

3

to było proste:

interf.isInstance(object) 
7

Wolę instanceof:

if (obj instanceof SomeType) { ... } 

który jest znacznie bardziej powszechne i czytelny niż SomeType.isInstance(obj)

+3

Należy pamiętać, że 'if (obj instanceof SomeType) {...}' jest statyczne (to znaczy - nie może się zmienić w czasie wykonywania) i 'SomeType.isInstance (obj)' jest dynamiczne. –

2

Jeśli chcesz przetestować interfejsy:

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

}

clazz to interfejs i myType jest Tyoe które określono, że może realizować szereg interfejsów. Z tym kodem można dostać tylko te typy, które implementują określonego interfejsu

0

z ArrayUtils Apache Commons-Lang, sprawdzić, czy interfejs wymagany jest zawarty w interfejsach z Was obiektów

public static Boolean implementsInterface(Object object, Class interf){ 
    return ArrayUtils.contains(object.getClass().getInterfaces(), interf); 
} 
1

I miał ten problem dzisiaj z Androidem i po zapoznaniu się z rozwiązaniami javadoc wymyśliłem to działające rozwiązanie tylko dla ludzi takich jak ja, którzy potrzebują trochę więcej niż wyjaśnień javadoc.

Oto działający przykład z rzeczywistym interfejsem wykorzystującym Android Java. Sprawdza działanie, które wywołało implementację interfejsu AboutDialogListener przed próbą rzutowania pola AboutDialogListener.

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; 
     } 
} 

... Potem sprawdź, czy pole jest ADL! Zerowy przed wywołaniem interfejsu

@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()); 
    } 
} 
Powiązane problemy