Hi,
I am writing a utility that finds all the classes implementing a particular interface.
It works like this:
1. Collects all the classpath elements from the System properties, including "java.class.path", "java.ext.dirs", etc.
2. Searches the directories in the classpath elements for java class files.
3. Uses method "forName()" in class "java.lang.Class" to load each class found as well as all classes in relevant java archives including JARs, ZIPs, EARs and WARs.
4. Uses java reflection to determine whether a class implements the relevant interface.
When loading the class, using method "forName()", any static initializers in the class are executed.
Can I prevent this from happening?
And if so, then how?
If anyone has an alternative suggestion as to how to find all classes implementing a particular interface, I would be very happy to hear it.
When loading the class, using method "forName()", any static initializers in the class are executed.
Can I prevent this from happening?
And if so, then how?
I am not aware of any such method. I dont think one exists.
If anyone has an alternative suggestion as to how to find all classes implementing a particular interface, I would be very happy to hear it.
Avi Abrami wrote:When loading the class, using method "forName()", any static initializers in the class are executed.
Can I prevent this from happening?
And if so, then how?
Use the overloaded forName method that takes a boolean and a class loader:
Adam Michalik
Ranch Hand
Joined: Feb 18, 2008
Posts: 128
posted
0
I do not think there is a way to avoid running the class initializers. To get the implemented interfaces you'd need to have code like
You can obtain the clazz instance in various ways (via Class.forName or using a class loader) but you need to call the getInterfaces method. And to do that, the class will need to be loaded and initialized. If you really don't want to load the classes, you may parse the .class files (see class file format) but it's a really, really tough and cumbersome task.
Adam Michalik
Ranch Hand
Joined: Feb 18, 2008
Posts: 128
posted
0
Rob Prime wrote:Use the overloaded forName method that takes a boolean and a class loader:
Haha, okay, that's much simpler :D Thanks, Rob, for the enlightenment ;)
Campbell Ritchie
Sheriff
Joined: Oct 13, 2005
Posts: 32654
4
posted
0
Wouldn't the instanceof operator help?
Adam Michalik
Ranch Hand
Joined: Feb 18, 2008
Posts: 128
posted
0
Well, to use the instanceof operator you need an instance of a class. And for that you need to: 1) initialize it, which you wanted to avoid, 2) run a constructor, which is not always possible.
Joanne Neal
Rancher
Joined: Aug 05, 2005
Posts: 3011
9
posted
0
Is there any reason you didn't use the Class.getInterfaces() method ?
Joanne
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35241
7
posted
0
You could also use a library like BCEL to get at class information without instantiating it.
Avi Abrami wrote:Rob,
I went with your suggestion regarding the overloaded "forName()" method.
However, as opposed to your example, I used:
What is the difference between the way I retrieve the "ClassLoader" and the way you do it?
this.getClass().getClassLoader() returns the class loader used to load that class. Thread.currentThread().getContextClassLoader() returns the class loader used at the time of the call. Although usually the same, if you use Class.forName with a different class loader (mostly a URLClassLoader) they can be different.
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35241
7
posted
0
Avi Abrami wrote:Do you have a link to it?
Google should lead you right to it.
Bauke Scholtz
Ranch Hand
Joined: Oct 08, 2006
Posts: 2458
posted
0
If you can/want to do this from the other way, the Class#isAssignableFrom() may be more useful.
Adam Michalik wrote:Well, to use the instanceof operator you need an instance of a class. And for that you need to: 1) initialize it, which you wanted to avoid, 2) run a constructor, which is not always possible.
Thank you. I hadn't realised the idea was to avoid creating instances.
Adam Michalik
Ranch Hand
Joined: Feb 18, 2008
Posts: 128
posted
0
Campbell Ritchie wrote:
Adam Michalik wrote:Well, to use the instanceof operator you need an instance of a class. And for that you need to: 1) initialize it, which you wanted to avoid, 2) run a constructor, which is not always possible.
Thank you. I hadn't realised the idea was to avoid creating instances.
Oh, in 1) by "you" I meant Avi, sorry. He wrote
When loading the class, using method "forName()", any static initializers in the class are executed.
Can I prevent this from happening?
So the idea was to avoid even initializing the class.