I have an Enum called Plugins:
public enum Plugins {
ROTATING_LINE (plugin.rotatingline.RotatingLine.class),
SNOW_SYSTEM (plugin.snow.SnowSystem.cla
Enums in this situtation will make your life more difficult.
In the past I've solved this problem this way:
class PluginFactory {
private Class clazz;
PluginFactory(Class clazz) {
this.clazz = clazz;
}
T newInstance() {
return clazz.newInstance();
}
final static PluginFactory SNOW_SYSTEM_FACTORY =
new PluginFactory(SnowSystem.class);
...
// should really use a list and a wilcard generic bounded by Plugin, but it's
// too verbose for me for the purposes of this answer
final static PluginFactory[] FACTORIES = {SNOW_SYSTEM_FACTORY, ...};
public static void main(String[] args) {
Plugin[] arr = new Plugin[FACTORIES.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = FACTORIES[i].newInstance();
}
// more usefully though
SnowSystem ss = SNOW_SYSTEM_FACTORY.newInstance();
ss.setValue(123);
}
}
The other option is to give newInstance var args object parameter. Then use reflections to find the appropriate constructor that takes these types as parameters. This is hideously messy and completely unsafe if a user of the API gives a bad set of arguments (exception thrown).
public T newInstance(Object... args) {
for (Constructor c : clazz.getConstructors()) {
if (isMatchingConstructor(c, args)) {
return clazz.cast(c.newInstance(args));
}
}
throw new NoSuchMethodException("No matching constructor found for args: "
+ Arrays.toString(args));
}
private boolean isMatchingConstructor(Constructor c, Object... args) {
Class>[] parameters = c.getParameterTypes();
if (parameters.length != args.length) {
return false;
}
for (int i = 0; i < args.length; i++) {
if (!parameters[i].isAssignableFrom(args[i].getClass())) {
return false;
}
}
return true;
}