162

This has probably been asked before, but a quick search only brought up the same question asked for C#. See here.

What I basically want to do is to check wether a given object implements a given interface.

I kind of figured out a solution but this is just not comfortable enough to use it frequently in if or case statements and I was wondering wether Java does not have built-in solution.

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


EDIT: Ok, thanks for your answers. Especially to Damien Pollet and Noldorin, you made me rethink my design so I don't test for interfaces anymore.
Community
  • 1
  • 1
sebastiangeiger
  • 3,386
  • 7
  • 29
  • 37
  • 3
    Can't you just try casting and catch the exception if one is thrown (or check for a null result even, if Java has anything analagous to the C# "as" operator)? I'm a C# coder rather than a Java one, so I'm mainly just guessing here, though I would think such an approach would be possible in any OO language. – Noldorin Apr 19 '09 at 21:21
  • 1
    Throwing exception is good practice in this case only if you don't have to care about performance. – Rafa Jan 22 '14 at 08:57
  • 2
    Pardon me but where are those answers made you re-think your design? Even if they deleted, what were they? Could you please help me @sebastiangeiger – ozanmuyes May 24 '16 at 20:18
  • 1
    @ozanmuyes I'm sorry, I haven't written Java in over 4 years and unfortunately I can't remember what I did. – sebastiangeiger May 26 '16 at 05:22

7 Answers7

203

The instanceof operator does the work in a NullPointerException safe way. For example:

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

yields true. Since:

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

yields false, the instanceof operator is null safe (the code you posted isn't).

instanceof is the built-in, compile-time safe alternative to Class#isInstance(Object)

Will Brode
  • 1,026
  • 2
  • 10
  • 27
dfa
  • 114,442
  • 31
  • 189
  • 228
  • 6
    instanceof only works on class literals though. So it can't be used in the OP's case – LordOfThePigs Apr 20 '09 at 00:07
  • sure, it is compile-time safe; and it is the built-in way and it is the argument of the question (imho) – dfa Apr 20 '09 at 08:10
  • @LordOfThePigs no it doesn't. It checks if an interface is implemented aswell. – NimChimpsky Jan 24 '14 at 10:16
  • 5
    @NimChimpsky: you misunderstood my point. Class literals is when you write things like `MyClass.class` or `MyInterface.class` in your source code. Class literals can refer to classes, interfaces and primitive types, and will return a corresponding instance the Class class. My point is the OP is not using a class literal, but an instance of the Class class instead, and unfortunately the right hand side operator of the `instanceof` keyword must be a class literal, not an instance of the Class class. – LordOfThePigs Jan 24 '14 at 10:55
  • @dsdsdsdsd Since this post I didn't even heard/read about it, but after looking up on Google I figured it out it is abbreviation of the Null Pointer Exception. – ozanmuyes May 24 '16 at 20:21
43

This should do:

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

For example,

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

evaluates to true.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
9

I prefer instanceof:

if (obj instanceof SomeType) { ... }

which is much more common and readable than SomeType.isInstance(obj)

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
  • 6
    Remember that `if (obj instanceof SomeType) { ... }` is static (that is - it cannot change at runtime) and `SomeType.isInstance(obj)` is dynamic. – Tomasz Bielaszewski Nov 02 '13 at 09:29
5

that was easy :

   interf.isInstance(object)
Andreas Petersson
  • 16,248
  • 11
  • 59
  • 91
3

If you want to test for interfaces:

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 is an Interface and myType is a Type that you defined that may implement a number of interfaces. With this code you get only the types that implement a defined interface

Alexander Terp
  • 199
  • 2
  • 12
Rafa
  • 2,328
  • 3
  • 27
  • 44
1

I had this problem tonight with android and after looking at the javadoc solutions I came up with this real working solution just for people like me that need a little more than a javadoc explanation.

Here's a working example with an actual interface using android java. It checks the activity that called implemented the AboutDialogListener interface before attempting to cast the AboutDialogListener field.

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

... Later I check if the field adl is !null before calling the interface

@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());
    }
}
danny117
  • 5,581
  • 1
  • 26
  • 35
0

With Apache commons-lang ArrayUtils, see if the interface you require is contained in the interfaces of you object

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