确定 Class 是否在 Java 中实现接口

我有一个 Class物体。我想确定 Class对象表示的类型是否实现了特定的接口。我想知道如何才能做到这一点?

我有以下密码。基本上,它所做的就是获取一个包含指定包中所有类的数组。然后,我想遍历数组并添加实现映射接口的 Class 对象。问题是 isInstance()接受一个对象作为参数。我不能实例化一个接口。所以我有点不知所措。有什么想法吗?

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
if(clazz.isInstance(/*Some object*/)) //Need something in this if statement
{
retVal.put(clazz.getSimpleName(), clazz);
}
}
79056 次浏览

You should use isAssignableFrom:

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

you can use the below function to get all the implemented interfaces

Class[] intfs = clazz.getInterfaces();

You can also set the instance adding ".class"

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
if(Interface.class.isAssignableFrom(clazz))
{
retVal.put(clazz.getSimpleName(), clazz);
}
}

You can use class.getInterfaces() and then check to see if the interface class is in there.

Class someInterface; // the interface you want to check for
Class x; //
Class[] interfaces = x.getInterfaces();


for (Class i : interfaces) {
if (i.toString().equals(someInterface.toString()) {
// if this is true, the class implements the interface you're looking for
}
}

A contribution for all the other answers, when possible do not use the most updated answer of method isAssignableFrom, even the "not great" answer of using clazz.getInterfaces() has better performance than isAssignableFrom.

A common mistake for developers when looking for an answer to the OP question, is to prefer isAssignableFrom when an instance is available, wrongly doing this:

if (IMyInterface.isAssignableFrom(myObject.getClass())) {
...

When possible, use IMyInterface.class.isInstance or instanceof as both of those have way better performance. Of course, as the OP stated; they have the drawback that you must have an instance and not just the class.

if (IMyInterface.class.isInstance(myObject)) {
...
if (myObject instanceof IMyInterface) { // +0.2% slower than `isInstance` (*see benchmark)
...

An even faster, but ugly solution would be to store an static Set with all the "valid" classes instead of checking them, this ugly solution is only preferred when you need to test classes a lot, as its performance outperforms all the other approaches for direct class check.

public static final Set<Class<?>> UGLY_SET = Stream.of(MyClass1.class, MyClass2.class, MyClass3.class).collect(Collectors.toCollection(HashSet::new));
if (UGLY_SET.contains(MyClass)) {
...

(*) JMH Benchmark for +0.2%

Please visit this answer from users @JBE, @Yura and @aleksandr-dubinsky, credits for them. Also, there's plenty of detail in that answer for the benchmark results to not be valid, so please take a look into it.