我有一个包含一个接口和几个类的包,这个包中的一些类实现了该接口,在一个没有实现该接口的类中,我想编写一个方法来返回实现该类的所有类的对象接口,我不知道实现该接口的类的名称,我该如何编写这个方法?
答案 0 :(得分:2)
此问题没有直接的解决方案,但我建议您使用reflections库。
一旦你拥有它,你就可以这样做:
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeClassOrInterface>> subTypes =
reflections.getSubTypesOf(SomeClassOrInterface.class);
答案 1 :(得分:1)
通常,java反射API中缺少此类功能。但你可以很容易地自己实现它。
您可以使用systemp属性java.class.path来获取所有classpath元素。使用属性path.separator拆分它。然后迭代结果数组,使用JAR API读取每个jar文件,实例化每个Class并检查您的接口是否为AssignableFrom(theClass)。
以下是查找类路径中可用的所有BSF引擎的代码段。我为我今天工作的博客文章写了这篇文章。此代码有限制:它仅适用于jar文件。我认为这足以解释这个想法。
private static Map<String, Boolean> getEngines() throws Exception {
Map<String, Boolean> result = new HashMap<String, Boolean>();
String[] pathElements = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
for (String pathElement : pathElements) {
File resource = new File(pathElement);
if (!resource.isFile()) {
continue;
}
JarFile jar = new JarFile(resource);
for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
JarEntry entry = e.nextElement();
if(entry.isDirectory()) {
continue;
}
if(!entry.getName().endsWith("Engine.class")) {
continue;
}
String className = entry.getName().replaceFirst("\\.class$", "").replace('/', '.');
try {
if(BSFEngine.class.getName().equals(className)) {
continue;
}
Class<?> clazz = Class.forName(className);
if(BSFEngine.class.isAssignableFrom(clazz) && !clazz.equals(BSFEngine.class)) {
result.put(className, true);
}
} catch (NoClassDefFoundError ex) {
// ignore...
result.put(className, false);
}
}
}
return result;
}
该方法返回Map,其中引擎类名称用作键,布尔值表示引擎是否可用。如果引擎在类路径中需要其他类,则引擎不可用。
答案 2 :(得分:0)
如果我正确理解你的问题,你需要一种方法来检查,列表中的特定类是否实现了一些特定的接口。您可以使用Class.getInterfaces()方法。
如果您在列出特定套餐中的所有课程时遇到麻烦,您可以查看一下,例如this question以及其他链接。