103

我有一个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);
    }
}
4

5 回答 5

243

你应该使用isAssignableFrom

if (YourInterface.class.isAssignableFrom(clazz)) {
    ...
}
于 2012-08-27T15:47:51.170 回答
18

您可以使用以下函数来获取所有实现的接口

Class[] intfs = clazz.getInterfaces();
于 2012-08-27T15:49:01.870 回答
10

您可以使用class.getInterfaces()然后检查接口类是否在其中。

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
    }
}
于 2012-08-27T15:51:27.417 回答
1

您还可以设置添加“.class”的实例

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
    if(Interface.class.isAssignableFrom(clazz))
    {
        retVal.put(clazz.getSimpleName(), clazz);
    }
}
于 2012-08-27T15:50:35.507 回答
0

对所有其他答案的贡献,尽可能不要使用方法的最新答案isAssignableFrom,即使使用的“不是很好”的答案clazz.getInterfaces()也比isAssignableFrom.

开发人员在寻找 OP 问题的答案时的一个常见错误是更喜欢isAssignableFrom实例可用时,错误地这样做

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

如果可能,使用IMyInterface.class.isInstanceinstanceof两者都有更好的性能。当然,它们的缺点是您必须有一个实例,而不仅仅是class.

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

一个更快但丑陋的解决方案是存储List所有“有效”类的静态而不是检查它们,这种丑陋的解决方案仅在您需要大量测试类时才是首选,因为它的性能优于所有其他方法。

public static final List<Class<?>> UGLY_LIST = Arrays.asList(MyClass1.class, MyClass2.class, MyClass3.class);
if (UGLY_LIST.contains(MyClass)) {
    ...
于 2022-02-26T18:31:26.333 回答