javaReflection return a list of classes that implement specific interface
I have a package which contains an interface and several classes,some classes in this package implement that interface ,In one class that does not imple开发者_StackOverflow中文版ment that interface,I want to write a method that returns an object of all classes which implement that interface,I dont know the name of classes which implement that interface,how can I write this method?
Generally such functionality is missing in java reflection API. but your can probably implement it yourself pretty easily.
Shortly you can use systemp property java.class.path to get all classpath elements. Split it using property path.separator. Then iterate over the resulted array, read each jar file using JAR API, instantiate each Class and check if your interface isAssignableFrom(theClass).
Here is the code snippet that looks for all BSF engines available in your classpath. I wrote it for my blog post I am working on this days. This code has limitation: it works with jar files only. I believe it is enough to explain the idea.
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;
}
The method returns Map where engine class name is used as a key and boolean value indicates whether the engine is available. Engine is unavailable if it requires additional classes in classpath.
There is no straightforward solution for this problem but I suggest you to use reflections library.
Once you have it, you can just do:
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeClassOrInterface>> subTypes =
reflections.getSubTypesOf(SomeClassOrInterface.class);
If I understand your question correctly, you need a way to check, whether particular class from the list implements some specific interface. You may use Class.getInterfaces() method for that.
If you have troubles with listing all classes from particular package, you may take a look, for example, at this question and at further links there.
精彩评论