概述
在这个教程中,我们将探讨几种方法来确定一个对象或类是否实现了特定的接口。
2. 使用Java反射API
Java反射API提供了多种方式来检查一个对象或类是否实现了接口。使用这个API可以避免在项目中添加第三方库。
2.1. 数据模型
Java运行环境(JRE)提供了一些方法来获取类实现的接口。首先,我们定义一个模型,包含一些接口和类:
定义一个接口
MasterInterface
,以及两个扩展它的子接口:
类方面,有一个实现
MasterInterface
的类,以及两个分别实现ChildInterface1
和ChildInterface2
的子类:
以下是我们的模型代码:
public interface MasterInterface {}
public interface ChildInterface1 extends MasterInterface {}
public interface ChildInterface2 extends MasterInterface {}
public class MasterClass implements MasterInterface {}
public class ChildClass1 implements ChildInterface1 {}
public class ChildClass2 implements ChildInterface2 {}
2.2. getInterfaces()
方法
Java API在Class
对象上提供了getInterfaces()
方法,用于获取一个类实现的所有接口。我们可以用以下代码获取一个类的所有直接实现接口:
List<Class<?>> interfaces = Arrays.asList(childClass2.getClass().getInterfaces());
assertEquals(1, interfaces.size());
assertTrue(interfaces.contains(ChildInterface2.class));
注意:这种方法只返回直接实现的接口,不检测接口的继承关系。
如果我们想获取完整的继承树,需要递归遍历实现的接口,直到找到根接口:
static Set<Class<?>> getAllExtendedOrImplementedInterfacesRecursively(Class<?> clazz) {
Set<Class<?>> res = new HashSet<Class<?>>();
Class<?>[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
res.addAll(Arrays.asList(interfaces));
for (Class<?> interfaze : interfaces) {
res.addAll(getAllExtendedOrImplementedInterfacesRecursively(interfaze));
}
}
return res;
}
执行后,我们可以验证我们在Set
中确实获取到了MasterInterface
:
assertTrue(interfaces.contains(ChildInterface2.class));
assertTrue(interfaces.contains(MasterInterface.class));
现在,我们有能力检查模型中的对象是否实现了特定的接口。
2.3. isAssignableFrom()
方法
前面的方法较为繁琐,Java API提供了更简洁的方法来检查Object
是否实现了接口,即使用Class
对象的isAssignableFrom()
方法。
这个方法如果对象继承了指定的接口,即使不是直接实现,也会返回true
:
ChildClass2 childClass2 = new ChildClass2();
assertTrue(MasterInterface.class.isAssignableFrom(childClass2.getClass()));
2.4. isInstance()
方法
Class
对象还提供了isInstance()
方法,它会返回提供的对象是否实现了接口:
assertTrue(MasterInterface.class.isInstance(childClass2));
2.5. instanceOf
运算符
最后一种检查方法是使用instanceOf
运算符,它同样适用于接口:
assertTrue(childClass2 instanceof MasterInterface);
3. 使用Apache Commons库
Apache Commons Lang库提供了几乎所有的实用类。ClassUtils
类能够列出一个类实现的所有接口。
首先,我们需要在pom.xml
中添加Maven中央仓库的依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
这与使用getInterfaces()
方法类似,但只需要一行代码:
List<Class<?>> allSuperInterfaces = ClassUtils.getAllInterfaces(childClass2.getClass());
这将递归返回所有实现的接口:
assertTrue(allSuperInterfaces.contains(ChildInterface2.class)); assertTrue(allSuperInterfaces.contains(MasterInterface.class));
4. 使用Reflections库
Reflections库是一个第三方库,它可以扫描我们的对象并允许我们针对收集到的元数据运行查询。
首先,我们需要在pom.xml
中添加Maven中央仓库的依赖:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
在运行查询之前,库需要先收集数据,因此需要初始化:
Reflections reflections = new Reflections("com.baeldung.checkInterface");
这个操作会扫描整个提供的类路径,可能需要一段时间才能完成。通常可以在应用启动时进行,以便后续查询能顺利进行。
然后,我们可以获取一个类实现的接口列表:
Set<Class<?>> classes = reflections.get(ReflectionUtils.Interfaces.of(ChildClass2.class));
5. 总结
本文介绍了检查类是否实现特定接口的不同方法。根据应用程序的需求,我们可以选择使用标准的Java反射API,或者如果需要更强大的功能,可以依赖第三方库。
如需查看完整代码,请访问GitHub。