Reputation: 6184
For the given Interface IfA
with class A
implementing it and class B
extending A
, I'd like to determine which of both classes A
and B
explicitly declare implementing the interface IfA
.
Obviously IfA.class.isAssignableFrom(A.class)
and IfA.class.isAssignableFrom(B.class)
are both true
. I hoped for a Method like
B.class.declaresInterface(IfA.class)
-> false
A.class.declaresInterface(IfA.class)
-> true
But something like this does not exist, does it?
Background: from some variable Class<? extends IfA> x
; not knowing if it is A, B or some other class C extending A or B ... I'd like to search the upper most super class implementing the interface. Currently I'm implying a somewhat ugly search for this:
public class SomeTest {
@org.junit.Test
public void testIt() {
assertTrue(IfA.class.isAssignableFrom(A.class));
assertTrue(IfA.class.isAssignableFrom(B.class));
Class<? extends IfA> b = B.class;
Class<?> result = b;
// somewhat ugly search: from B.class find A.class
while (IfA.class.isAssignableFrom(result.getSuperclass())) {
result = result.getSuperclass();
}
Object s = result.getSuperclass();
assertSame(A.class, result);
assertFalse(IfA.class.isAssignableFrom(result.getSuperclass()));
}
interface IfA {
};
class A implements IfA {
};
class B extends A {
};
}
Is there a more explicity way of interface detection, making the search easier to understand?
Upvotes: 2
Views: 73
Reputation: 88707
Afaik there's no declaresInterface(...)
method in the JDK itself although there might be a library that provides one.
The Class
class itself provides the a method called getInterfaces()
which according to the JavaDoc:
Returns the interfaces directly implemented by the class or interface represented by this object.
Thus an implementation for boolean declaresInterface(Class<?> clazz, Class<?> interface )
should be quite straight forward (though performance might be improved using some caching):
boolean declaresInterface(Class<?> clazz, Class<?> iface) {
//note: you should add some checks, e.g. for null and correct types
return Arrays.stream( clazz.getInterfaces() )
.anyMatch( iface::equals );
}
Tests:
//true because Integer implements Comparable<Integer>
declaresInterface( Integer.class, Comparable.class );
//false, because Integer extends Number and Number implements Serializable
declaresInterface( Integer.class, Serializable.class );
Upvotes: 4