如何确定一个Java类是否实现了特定的接口

12

我正在尝试使用反射来确定一个传入的类是否实现了 IsWdidget 接口:

public boolean isAWidget(Class<?> clzz) {
    Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName());
    Class<?>[] impls = runtimeClass.getInterfaces();
    for(Class<?> clz : impls)
        if(clz.getName().equals(IsWidget.class.getName()))
            return true;

    return false;
}

这是确定这个的最佳/最有效的方法吗?我还看到一个IsWidget.class.isAssignableFrom(Class<?>)方法...

4个回答

14

我会使用isAssignableFrom方法来确定IsWidget是否是一个超级接口:

return IsWidget.class.isAssignableFrom(clzz);

引用上面链接的Javadoc:

确定由此Class对象表示的类或接口是否与指定的Class参数所表示的类或接口相同,或者是其超类或超接口。


1
1)这没有意义。
  Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName());

尝试在任何类中使用此代码。
    Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName());
    System.out.println(runtimeClass == clzz);

你将得到。
true

如果您删除这行并直接使用clzz,它已经更加高效了。
2)试试这个。
class X extends Thread {
}

public static void main(String[] args) throws ClassNotFoundException {
    System.out.print(Arrays.toString(X.class.getInterfaces()));
}

你将会得到。
[]

这类似于您的函数正在做的事情,但实际上X实现了Runnable接口。
3)这是一种非常高效的一行解决方案,用于检查一个类是否实现了一个接口。
    System.out.print(Runnable.class.isAssignableFrom(X.class));

输出

true

1
如果您拥有一个Class对象,可以使用getInterfaces()方法。
    Class c[] = clzz.getInterfaces();   
    if(Arrays.asList(c).contains(IsWidget.class))
    {
        return true;
    }

getInterfaces方法会返回一个代表接口的Class数组。或者你也可以使用isAssignableFrom方法,如下:

IsWidget.class.isAssignableFrom(clzz);

如果你有一个 Object,你可以使用 instanceof 方法。

这将确定clzz是否是IsWidget的超类;它是相反的。 - rgettman
@rgettman:已更正。感谢您的通知。:) - Rahul Bobhate

0

如果这样行得通的话,那就没问题了。你也可以尝试调用 Class 类的 cast 方法,并进行异常捕获。


这确实可以工作,但它真的滥用了使用try/catch块的目的。而且抛出的异常会使调用变得更加昂贵,不过我不确定使用反射来确定实现接口会更有效率多少。 - codewario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接