2009-04-19 14 views
121

Probabilmente è stato chiesto prima, ma una ricerca rapida ha richiamato solo la stessa domanda per C#. See here.Verifica se l'interfaccia degli oggetti implementa

Quello che sostanzialmente voglio fare è controllare se un dato oggetto implementa una determinata interfaccia.

Ho trovato una soluzione, ma questo non è abbastanza comodo per usarlo spesso nelle istruzioni if ​​o case e mi chiedevo se Java non avesse una soluzione integrata.

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


EDIT: Ok, grazie per le vostre risposte. Soprattutto con Damien Pollet e Noldorin, mi hai fatto ripensare al mio design in modo da non provare più le interfacce.

+3

Non puoi semplicemente cercare di casting e intercettare l'eccezione, se si è gettato (o verificare la presenza di un risultato nullo, anche se Java ha qualcosa di analogo al C# "come" operatore)? Sono un programmatore C# piuttosto che uno Java, quindi principalmente indovinerei qui, anche se penserei che un simile approccio sarebbe possibile in qualsiasi linguaggio OO. – Noldorin

+0

yay! prego :) –

+0

L'eccezione di lancio è una buona pratica in questo caso solo se non ti devi preoccupare delle prestazioni. – Rafa

risposta

159

L'operatore instanceof fa il lavoro in modo sicuro NullPointerException. Ad esempio:

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

restituisce true. Dal:

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

cede falso, l'operatore instanceof è sicuro null (il codice che hai postato non è).

instanceof è il built-in, a tempo di compilazione sicura alternativa alla Class#isInstance(Object)

+4

instanceof funziona solo sui letterali di classe. Quindi non può essere utilizzato nel caso dell'OP – LordOfThePigs

+0

sicuro, è sicuro in fase di compilazione; ed è il modo integrato ed è l'argomento della domanda (imho) – dfa

+0

@LordOfThePigs no non lo fa. Controlla se anche un'interfaccia è implementata. – NimChimpsky

40

Questo dovrebbe fare:

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

Per esempio,

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

viene valutato come true.

+1

+1 - questo non fallirà se l'oggetto è nullo – msangel

3

che era facile:

interf.isInstance(object) 
7

preferisco instanceof:

if (obj instanceof SomeType) { ... } 

, che è molto più comune e leggibile di SomeType.isInstance(obj)

+3

Ricorda che 'if (obj instanceof SomeType) {...}' è statico (cioè - non può cambiare in fase di esecuzione) e 'SomeType.isInstance (obj)' è dinamico. –

2

Se desidera testare le interfacce:

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 è un'interfaccia e myType è un Tyoe che è stato definito che può implementare un numero di interfacce. Con questo codice si ottiene solo i tipi che implementano un'interfaccia definita

0

Con ArrayUtils Apache commons-lang, vedere se l'interfaccia si richiede è contenuta nelle interfacce di voi opporsi

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

ho avuto questo problema stasera con Android e dopo aver esaminato le soluzioni javadoc, ho trovato questa soluzione reale solo per le persone come me che hanno bisogno di qualcosa in più di una spiegazione javadoc.

Ecco un esempio funzionante con un'interfaccia effettiva utilizzando Android Java. Controlla l'attività che ha richiamato l'interfaccia AboutDialogListener prima di tentare di eseguire il cast del campo 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; 
     } 
} 

... Più tardi ho verificare se l'ADL campo è! Null prima di chiamare l'interfaccia

@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()); 
    } 
}