3

Within the args[] of public static void main(String args[]) I would like to specify which subclass to implement. How can I convert a parameters of args[] (a String) into a class declaration?

For example, if args[0] = "Subclass1", then somewhere below I need to declare:
BaseClass b = new Subclass1()

Is this possible with Java?

EDIT
To make this one step trickier, these subclasses are coming from an external .jar. Is there any way to dynamically import the subclasses, or do they need to be imported beforehand?

Adam_G
  • 7,337
  • 20
  • 86
  • 148

3 Answers3

8

The class name should be the full path to the class , i.e. [package].[classname] You can use Class.forName([class name]).newInstance();

Arsen Alexanyan
  • 3,061
  • 5
  • 25
  • 45
  • Thanks! This is what I was looking for, but I'm going to go with @sp00m because of the more explicit declaration. – Adam_G Mar 01 '13 at 16:08
6
public static void main(String[] args) {
    if (args.length > 0) {
        // exceptions handling omitted
        Class<?> clazz = Class.forName(args[0]);
        // check before casting
        if (BaseClass.class.isAssignableFrom(clazz)) {
            BaseClass instance = (BaseClass) clazz.newInstance();
            // use
        }
    }
}

Note that className should be the full path to the class, i.e. not only Subclass1, but your.package.Subclass1.

sp00m
  • 47,968
  • 31
  • 142
  • 252
  • Question about this: This only can create an `Object`, right? Is it fine to cast it in that same line, or should I do that separately? – Adam_G Mar 01 '13 at 16:18
  • Thanks! That's what I assumed. – Adam_G Mar 01 '13 at 19:52
  • To make this one step trickier, these subclasses are coming from an external `.jar`. Is there any way to dynamically import the subclasses, or do they need to be imported beforehand? – Adam_G Mar 02 '13 at 00:33
  • @Adam_G See [this question](http://stackoverflow.com/q/60764/1225328) for further information about *why it is so difficult to load JARs dynamically at runtime*. – sp00m Mar 04 '13 at 08:26
2

If your main class is called com.acme.app.Main, and it has a subclass of public static class Subclass1, then use this code snippet:

Class<?> cls = Class.forName("com.acme.app.Main$"+args[0]);
Object instance = cls.getConstructor().newInstance();

The inner class is accessed via the $ mark.

Note that the cls.getConstructor().newInstance() is more recommended than the old cls.newInstance().

If you know that your inner class implements or extends a certain interface or class, then you can use Class<MyInterface> and MyInterface instance instead of general objects.

gaborsch
  • 15,408
  • 6
  • 37
  • 48
  • Why is `cls.getConstructor().newInstance()` recommended over `cls.newInstance()`? – Adam_G Mar 01 '13 at 16:12
  • 1
    Because with the first one you can catch `IllegalArgumentException` and `InvocationTargetException`, for example if you want to pass parameters. – gaborsch Mar 01 '13 at 16:17