Construct Object using class name

You can create an object dynamically at runtime using only the name of the class, input as a simple string. This is done using a part of the Java language called reflection.

Reflection allows old code to call new code, without needing to recompile.

If a class has a no-argument constructor, then creating an object from its package-qualified class name (for example, "java.lang.Integer") is usually done using these methods:

If arguments need to be passed to the constructor, then these alternatives may be used instead:

The most common use of reflection is to instantiate a class whose generic type is known at design-time, but whose specific implementation class is not. See the plugin topic for an example. Other uses of reflection are rather rare, and appear mostly in special-purpose programs.

Example

Interpreter is an interface used by a simple command line application to interpret user input:


import java.util.*;

/**
* Parse a line of text and return a result.
*/
public interface Interpreter {

  /**
  * @param aLine is non-null.
  * @param aResult is a non-null, empty List which acts as an "out"
  * parameter; when returned, aResult must contain a non-null, non-empty
  * List of items which all have a <code>toString</code> method, to be used
  * for displaying a result to the user.
  *
  * @return true if the user has requested to quit the Interpreter.
  * @exception IllegalArgumentException if a param does not comply.
  */
  boolean parseInput(String aLine, List<Object> aResult);

  /**
  * Return the text to be displayed upon start-up of the Interpreter.
  */
  String getHelloPrompt();
} 

The task is to create a concrete implementation of this interface at runtime, using only the name of a class as input. In this example, the user inputs a package-qualified class name directly on the command line. Then, a corresponding Object is created and cast to the expected type (here, Interpreter). The object can then be used in the same way as any other object.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

/**
* Sends text back and forth between the command line and an
* Interpreter. JDK less than 6.
*/
public final class Console {

  /**
  * Build and launch a specific <code>Interpreter</code>, whose
  * package-qualified name is passed in on the command line.
  */
  public static void main(String... aArguments) {
    try {
      Class theClass = Class.forName(aArguments[0]);
      Interpreter interpreter = (Interpreter)theClass.newInstance();
      Console console = new Console(interpreter);
      console.run();
    }
    catch (ClassNotFoundException ex){
      System.err.println(ex + " Interpreter class must be in class path.");
    }
    catch(InstantiationException ex){
      System.err.println(ex + " Interpreter class must be concrete.");
    }
    catch(IllegalAccessException ex){
      System.err.println(ex + " Interpreter class must have a no-arg constructor.");
    }
  }

  public Console(Interpreter aInterpreter) {
    if (aInterpreter == null) {
      throw new IllegalArgumentException("Cannot be null.");
    }
    fInterpreter = aInterpreter;
  }

  /**
  * Display a prompt, wait for a full line of input, and then parse
  * the input using an Interpreter.
  *
  * Exit when <code>Interpreter.parseInput</code> returns true.
  */
  public void run() {
    display(fInterpreter.getHelloPrompt());

    //pass each line of input to fInterpreter, and display
    //fInterpreter's result
    InputStreamReader inputStreamReader = new InputStreamReader(System.in);
    BufferedReader stdin = new BufferedReader(inputStreamReader);
    boolean hasRequestedQuit = false;
    String line = null;
    List<Object> result = new ArrayList<Object>();
    try {
      while(!hasRequestedQuit){
        line = stdin.readLine();
        //note that "result" is passed as an "out" parameter
        hasRequestedQuit = fInterpreter.parseInput(line, result);
        display(result);
        result.clear();
      }
    }
    catch (IOException ex) {
      System.err.println(ex);
    }
    finally {
      display(fBYE);
      shutdown(stdin);
    }
  }

  // PRIVATE
  private static final String fBYE = "Bye.";
  private Interpreter fInterpreter;

  /**
  * Display some text to stdout.
  * The result of toString() is used.
  */
  private void display(Object aText){
    System.out.print(aText.toString());
    System.out.flush();
  }

  /**
  * Display a List of objects as text in stdout, in the order returned
  * by the iterator of aText.
  */
  private void display(List<Object> aText) {
    for(Object item : aText){
      display(item);
    }
  }

  private void shutdown(Reader aStdin){
    try {
      aStdin.close();
    }
    catch (IOException ex){
      System.err.println(ex);
    }
  }
} 



See Also :
Console input
Abstract Factory
Plugin Factory
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -