Java Reflection 
by Paul Tremblett



Example 1:

public String methSubtract(int i1, int i2) {
   return Integer.toString(i1) + " - " +
     Integer.toString(i2) + " = " + Integer.toString(i1 - i2);
}


Listing One
// ReflectionDemo.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.Math;
import java.util.Random;
import java.util.StringTokenizer;

public class ReflectionDemo {

  Random rand;
  BufferedReader consoleIn;
  ReflectionDemo() {
    consoleIn = new BufferedReader(new InputStreamReader(System.in));
    rand = new Random();
  }
  String getCommandLine() throws IOException {
    System.out.print(">");
    System.out.flush();
    String commandLine = consoleIn.readLine();
    if (commandLine == null)
      return "Q";
    if (commandLine.length() == 0)
      return "Q";
    else
      return commandLine;
  }
  String extractCommand(String commandLine) {
    StringTokenizer t = new StringTokenizer(commandLine);
    String cmd = t.nextToken().toLowerCase();
    return cmd.substring(0,1).toUpperCase() + cmd.substring(1);
  }
  ArgumentHolder extractArguments(String cmd) {
    StringTokenizer t = new StringTokenizer(cmd);
    int tokenCount = t.countTokens();
    ArgumentHolder a = new ArgumentHolder();
    String token = t.nextToken();
    while(t.hasMoreTokens()) {
      token = t.nextToken();
      try {
        int i = Integer.parseInt(token);
        a.setArgument(i);
      }
      catch (NumberFormatException e) {
        a.setArgument(token);
      }
    }
    return a;
  }
  public String methAdd(int i1, int i2) {
    return Integer.toString(i1) + " + " + 
      Integer.toString(i2) + " = " + Integer.toString(i1 + i2);
  }
  public String methConcat(String s1, String s2) {
    return "the concatenated string is " + s1 + s2;
  }
  public String methH() {
    return methHelp();
  }
  public String methHelp() {
    final String[] helpMessages = 
      {"ReflectionDemo Version 1.0",
       "valid commands are:",
       "add int1 int2",
       "concat string1 string 2",
       "help",
       "minmax int1 int2 int3",
       "quit",
       "rand"
      };
    for (int i = 0; i < helpMessages.length; ++i)
      System.out.println(helpMessages[i]);
    return "";
  }
  public String methMinmax(int i1, int i2, int i3) {
    return ("min = " + 
      Integer.toString(java.lang.Math.min(java.lang.Math.min(
        i1,i2),i3)) + ", max = " + Integer.toString(
        java.lang.Math.max(java.lang.Math.max(i1,i2),i3)));
  }
  public String methQ() {
    return methQuit();
  }
  public String methQuit() {
    return "quitting";
  }
  public String methRand() {
    return "the random number is " + Integer.toString(rand.nextInt());
  }
  String processCommand(String cmd) {
    try {
      String meth = "meth" + extractCommand(cmd);
      ArgumentHolder a = extractArguments(cmd);
      return (String)(Invoker.dynaCall(this, meth,a));
    }
    catch (NoSuchMethodException e) {
      return "no method to process command " + cmd;
    }
    catch (InvocationTargetException e) {
      System.out.println("trace:");
      e.printStackTrace();
      return "InvocationTargetException processing command" + cmd;
    }
    catch (IllegalAccessException e) {
      System.out.println("trace:");
      e.printStackTrace();
      return "IllegalAccessException processing command" + cmd;
    } 
  }
  public static void main(String args[]) {
    boolean allOK = true;
    String line;

    ReflectionDemo myClient = new ReflectionDemo();

    System.out.println("Reflection Demo Version 1.0");
    System.out.println("Enter command at the prompt");
    System.out.println("Type h (or H) for help");
    while(allOK) {
      try {
        line = myClient.getCommandLine();
        if (line == null)
          allOK = false;
        else {
          System.out.println(myClient.processCommand(line));
          if (line.substring(0,1).toUpperCase().equals("Q")) 
            allOK = false;
        }
      }
      catch (IOException e) {
        e.printStackTrace();
        allOK = false;
      }
    }
    System.exit(0);
  }
}

Listing Two
//Invoker.java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Invoker {
  static Object dynaCall(Object c, String m, ArgumentHolder a) 
    throws NoSuchMethodException, InvocationTargetException, 
      IllegalAccessException {
    // Method meth;
    Method meth = c.getClass().getMethod(m, a.getArgumentClasses()); 
    return (meth.invoke(c, a.getArguments()));
  }
}

Listing Three
//ArgumentHolder.java
public class ArgumentHolder {
  protected Class[] cl;
  protected Object[] args;
  protected int argc;

  ArgumentHolder() {
    argc = 0;
    cl = new Class[0];
    args = new Object[0];
  }
  ArgumentHolder(int argc) {
    this.argc = argc;
    cl = new Class[argc];
    args = new Object[argc];
  }
  public Class[] getArgumentClasses() {
    return cl;
  }
  public Object[] getArguments() {
    return args;
  }
  public int setArgument(boolean b) {
    return this.setArgument(argc, new Boolean(b), Boolean.TYPE);
  }
  public int setArgument(int argnum, boolean b) {
    return this.setArgument(argnum, new Boolean(b), Boolean.TYPE);
  }
  public int setArgument(byte b) {
    return this.setArgument(argc, new Byte(b), Byte.TYPE);
  }

  public int setArgument(int argnum, byte b) {
    return this.setArgument(argnum, new Byte(b),Byte.TYPE);
  }
  public int setArgument(char c) {
    return this.setArgument(argc, new Character(c), Character.TYPE);
  }
  public int setArgument(int argnum, char c) {
    return this.setArgument(argnum, new Character(c),Character.TYPE);
  }
  public int setArgument(int i) {
    return this.setArgument(argc, new Integer(i), Integer.TYPE);
  }
  public int setArgument(int argnum, int i) {
    return this.setArgument(argnum, new Integer(i), Integer.TYPE);
  }
  public int setArgument(short s) {
    return this.setArgument(argc, new Short(s), Short.TYPE);
  }
  public int setArgument(int argnum, short s) {
    return this.setArgument(argnum, new Short(s), Short.TYPE);
  }
  public int setArgument(long l) {
    return this.setArgument(argc, new Long(l), Long.TYPE);
  }
  public int setArgument(int argnum, long l) {
    return this.setArgument(argnum, new Long(l), Long.TYPE);
  }
  public int setArgument(float f) {
    return this.setArgument(argc, new Float(f), Float.TYPE);
  }
  public int setArgument(int argnum, float f) {
    return this.setArgument(argnum, new Float(f), Float.TYPE);
  }
  public int setArgument(double d) {
    return this.setArgument(argc, new Double(d), Double.TYPE);
  }
  public int setArgument(int argnum, double d) {
    return this.setArgument(argnum, new Double(d), Double.TYPE);
  }
  public int setArgument(Object obj) {
    return this.setArgument(argc, obj, obj.getClass());
  }
  public int setArgument(int argnum, Object obj) {
    return this.setArgument(argnum, obj, obj.getClass());
  }
  public int setArgument(int argnum, Object obj, Class c) {
    if (argnum >= args.length) {
      argc = argnum + 1;
      Class[] clExpanded = new Class[argc];
      Object[] argsExpanded = new Object[argc];
      System.arraycopy(cl, 0, clExpanded, 0, cl.length);
      System.arraycopy(args, 0, argsExpanded, 0, args.length);
      cl = clExpanded;
      args = argsExpanded;
    }
    args[argnum] = obj;
    cl[argnum] = c;
    return argnum;
  }
}


Listing Four
//InvokerTest.java
import java.lang.reflect.InvocationTargetException;
import java.util.Vector;

public class InvokerTest {

  public void singleInteger(Integer i) {
    System.out.println("in method singleInteger() : i = " + i);
  }
  public void intOnly(int i) {
    System.out.println("in method intOnly() : i = " + i);
  }
  public void arrayTest(byte[] b) {
    System.out.println("in method arrayTest()");
    System.out.println("String from byte array is " + new String(b));
  }
  public void multi(int i, String s, Vector v) {
    System.out.println("in method multi()");
    System.out.println("s = " + s);
    System.out.println("i = " + i);
    System.out.println("v has " + v.size() + " elements");
  }
  public static void main(String args[]) {
    try {
      InvokerTest myInvoker = new InvokerTest();
      ArgumentHolder a1 = new ArgumentHolder();
      a1.setArgument(0,new Integer(1));
      Invoker.dynaCall(myInvoker, "singleInteger", a1);
      ArgumentHolder a2 = new ArgumentHolder();
      int i = 1;
      a2.setArgument(0,i);
      Invoker.dynaCall(myInvoker, "intOnly", a2);
      ArgumentHolder a3 = new ArgumentHolder();
      byte[] b = new String("abcde").getBytes();
      a3.setArgument(b);
      Invoker.dynaCall(myInvoker, "arrayTest", a3);
      ArgumentHolder am = new ArgumentHolder();
      i = 25;
      am.setArgument(i);
      am.setArgument("this is a test");
      Vector vv = new Vector();
      vv.addElement("a");
      vv.addElement("b");
      vv.addElement("c");
      vv.addElement("d");
      am.setArgument(vv);
      Invoker.dynaCall(myInvoker, "multi", am);
    }
    catch (IllegalAccessException e) {
      System.out.println(e);
    }
    catch (InvocationTargetException e) {
      System.out.println(e);
    }
    catch (NoSuchMethodException e) {
      System.out.println(e);
    }
    System.exit(0);
  }
}




