This might be a technically possible approach, but like other posters, I urge you to consider if this is the right way to solve your problem (and you've asked how to implement this solution rather than how to solve your original problem, so I can't really tell you if you're on the right track or not).
Are you perhaps interested in optionally depending on a library but not forcing your clients to provide it? Depending on your build system, this isn't that hard to accomplish. Maven, for example, allows you to specify a dependency as <scope>optional</scope>
, which allows you to compile code against it but doesn't include it as a transitive dependency.
That being said, it is indeed possible to optionally depend on certain libraries and to take an alternate route if they're not available. In my experience, this is most easily done by hiding the details behind an interface.
As an example, I have a ProfilingAdvisor interface that works with an AspectJ aspect to profile methods I've marked with a custom annotation. I have a rudimentary implementation of this interface called SimpleProfilingAdvisor, which has no external dependencies. I have a more detailed implementation that uses the Java Simon library for additional information, called SimonProfilingAdvisor.
If clients choose to include the Java Simon library, they get the "better" implementation. If they choose not to, the "base" approach is implemented (which in your case may be to do nothing at all).
My code always operates to the interface, ProfilingAdvisor, but when instantiating the instance variable of this type, I have to determine whether the optional Simon library is on the classpath:
private ProfilingAdvisor advisor;
/* ... */
try {
Class.forName("org.javasimon.SimonManager");
this.advisor = new SimonProfilingAdvisor();
} catch (ClassNotFoundException classNotFoundException) {
this.advisor = new SimpleProfilingAdvisor();
}
One last point. While you can determine a class's existence using reflection as you're suggesting, I can't think of anything you're gaining by making reflective method accesses to it after instantiation, and you're effectively bypassing the compiler's ability to so much as check your spelling on method names, etc.
At the least, you should be working with a build system that allows you to compile against a library at compile-time but not necessarily include it in your distribution later (e.g., Maven).