32

so I have this class in Java:

public class Foo<T>{
}

and inside this class I want to know if T implements certain interface.

The following code DOES NOT work but it's the idea of what I want to accomplish:

if(T.class implements SomeInterface){
    // do stuff
}

so I want to check if the class T that was passed to Foo have implements SomeInterface on its signature.

Is it possible? How?

Budius
  • 39,391
  • 16
  • 102
  • 144

3 Answers3

63

Generics, oddly enough, use extends for interfaces as well.1 You'll want to use:

public class Foo<T extends SomeInterface>{
    //use T as you wish
}

This is actually a requirement for the implementation, not a true/false check.

For a true/false check, use unbounded generics(class Foo<T>{) and make sure you obtain a Class<T> so you have a refiable type:

if(SomeInterface.class.isAssignableFrom(tClazz));

where tClazz is a parameter of type java.lang.Class<T>.

If you get a parameter of refiable type, then it's nothing more than:

if(tParam instanceof SomeInterface){

but this won't work with just the generic declaration.

1If you want to require extending a class and multiple interfaces, you can do as follows: <T extends FooClass & BarInterface & Baz> The class(only one, as there is no multiple inheritance in Java) must go first, and any interfaces after that in any order.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • 1
    hi. I really need the true/false check because I'm modifying an existing class. I'm trying your second code but still not sure where `tClass` come from. Any help on that ? – Budius Sep 13 '13 at 10:32
  • 1
    @Budius Your user needs to at some time, pass in either `Class` from `someInstanceOfT.getClass()` or to pass in an instance of `T` itself. Type erasure won't let you get it otherwise. – nanofarad Sep 13 '13 at 10:33
  • 1
    so I can't use the actual generic `T` to test for interface, I'll only be able to use it during `public void add(T object){...}` and test it on the `object`. – Budius Sep 13 '13 at 10:36
  • 1
    Sadly indeed, not sure it will match my requirements as I need to generate a filename on constructor. Any other way you can think to get the `serialVersionUID` of a possible `Serializable` ? – Budius Sep 13 '13 at 10:40
  • ok, I think I'm saved at the end. The guy who originally created this class created a `public abstract Class myclass();` so I could use `instanceof`. Thanks again. – Budius Sep 13 '13 at 10:53
  • It was harder than it should have been understanding that `class extends myInterface>` was the right syntax for a class function parameter for my case. Thanks for the thorough explanation! – slycrel Aug 08 '22 at 19:11
4

you can check it using isAssignableFrom

if (YourInterface.class.isAssignableFrom(clazz)) {
    ...
}

or to get the array of interface as

Class[] intfs = clazz.getInterfaces();
muthu
  • 5,381
  • 2
  • 33
  • 41
  • The OP needs a refiable type to get `clazz`, perhaps as accepting `Class` as a parameter or at construction. – nanofarad Sep 13 '13 at 10:26
0

Use isAssignableFrom()

isAssignableFrom() determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.

if (SomeInterface.class.isAssignableFrom(T class)) {
  //do stuff
}
Naveen Kumar Alone
  • 7,536
  • 5
  • 36
  • 57