Is it possible to get all the subclasses of a clas

2020-02-06 05:05发布

问题:

This question already has answers here:
Closed 10 years ago.

Possible Duplicate:
How do you find all subclasses of a given class in Java?

Hi,

I would like to get a list of classes that implement an interface in Java at runtime so I can do a lookup service without having to hard code it. Is there a simple way of doing this? I fear not.

回答1:

The short answer is no.

The long answer is that subclasses can come into existence in many ways, which basically makes it impossible to categorically find them all.

You can't do it at runtime but you can't find classes until they're loaded and how do you know they're loaded? You could scan every JAR and class file but that's not definitive. Plus there are things like URL class loaders.

Inner classes (static and non-static) are another case to consider. Named inner classes are easier to find. Anonymous inner classes are potentially much more difficult to find.

You also have to consider that if a class has subclasses then new subclasses can be created at a later point.



回答2:

you should use Java ServiceLoader that is a builtin class. It is capable of iterating at runtime over all know service (interface) implementations.

If for some reason you don't want it, you can use ClassLoader.getSystemResources() to iterate over all resources; e.g. if you have 6 times the file /META-INF/com.interface you'll get 6 iterations.



回答3:

I can always create a new subclass for any non-final class, add the subclass to the classpath, and defeat your intent. Subclassing is an open-ended proposition.

About the best you can do is say that for a given classpath, you know what the subclasses are, and to do that, you'd have to scan each class in the classpath.



回答4:

It's fairly simple using reflection. Read this article from JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html



回答5:

The only way you'd be able to do it is walking the package hierarchy for the packages available in the classpath checking each class via reflection (and that's gonna suck because you'll effectively load every class, unless you restrict your search to certain packages).

The trouble with this sort of auto-magical behavior is that it becomes hard to quantify the application without running it, which is a maintenance headache. I'd always prefer to go the injection route (a-la Spring) passing instances via some sort of configuration.



回答6:

I am trying to reason through the answer here so I am probably wrong. It would not make sense for a class to have information about its descendants or subclasses because at any point in time someone can create a new subclass of your class. Then you would have to recompile your class to include this new information every time. This does not make sense for extendable code. It is more likely for a class to contain information about its ancestors. So the only solution that I can see is for you to iterate over every class in your problem space and check but this is more than likely a horrible solution for you.



回答7:

Do you want to enumerate classes that implement a particular interface or enumerate classes that derive from some base class? These are two different issues. Both as far as I know would be hard to implement since new implementations can be created/installed on a PC at any time in the future. It sounds like you are trying to create a factory method to instantiate a particular instance and you don't want to hard-code the class name in the code. Usually using a config file that enumerates all the classes that implement the interface is the way to go (or a database can be used). As new classes implement the interface, you add them to the config file and the factory should pick up the new class name.



回答8:

If you only load classes from the disk or from URLs then you can scan the classpath and find subclasses "manually".