I've an interface implemented by classes that perform a file processing, say searching or whatever.
public interface FileProcessorInterface {
public void processFile(String fileName);
}
Then i have a different implementation for each file type:
public class TxtProcessor implements FileProcessorInterface {
@Override public void processFile(String fileName) { //do the work }
}
Thus i have the Utilizer of the processor, that has a method that allows for registering each class, something like this:
class Utilizer {
Map <String, Class> registered = new HashMap<>();
public void registerClass(String fileExt, Class clazz) {
registered.put(fileExt, clazz);
}
public void processFile(String fileName) {
//1) get the registered class from registered map (omitted because easy and not relevant)
//2) create an instance of the class using reflection (omitted because easy and not relevant)
FileProcessorInterface p = ....
p.processFile(fileName);
}
So far it's ok.
Now, i'm providing many implementations of my interface.
And i am tempted to provide each implementation class with a static initializer that register itself in the Utilizer, in the case of my previous TxtProcessor it would be:
class TxtProcessor implements FileProcessorInterface {
//previous code
static {
Utilizer.registerClass("txt", TxtProcessor.class);
}
}
The problem is that this static method will never be called because in the "statically reachable" code of the application there is no reference to my TxtProcessor class, since it is instantiated via reflection. So the jvm does not call the static initializer.
Say that i have two parts: the "generic code" that is the Utilizer and on the other side the implementations; it has to be thought as something provided dinamically and so it is not known by the Utilizer part.
Infact the idea was exactly that each class would register itself leaving the Utilizer untouched.
It is hard for me conceiving a solution that does not put some form of 'knowledge' of the implementations on the Utilizer side (and that stays simple), just because of the problem of the static initializer not called. How to overcome this?
You can look at Reflections library. It allow you to find all the classes which implement an interface, have an annotation or extend a class.