Browse DevX
Sign up for e-mail newsletters from DevX


Build a Reflection-based Interpreter in Java : Page 3

Java's support of reflection enables you to create an interpreter that executes commands interactively. This article demonstrates how to build a reflection-based system that allows simple scripting of Java programs without having to install a special-purpose scripting language. It also provides a downloadable sample program.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

The program parses each command using java.util.StringTokenizer. This breaks the command up into words by splitting it at whitespace as follows:

StringTokenizer st = new StringTokenizer( line ); List tokens = new ArrayList(); while (st.hasMoreTokens()) { String token = st.nextToken(); tokens.add( token ); }

This is a relatively simple parsing method, but it's sufficient for your purposes.

Finding the Class
Once we've got the command line broken up into words, you have access to the first word, which is the class name:

String className = line[0]; try { Class clas = Class.forName( className ); } catch( ClassNotFoundException cnfe ) { throw new CommandLineException( "Can't find class "+className ); }

Loading the class is as easy as calling Class.forName(), which looks for the specified class in the classpath. This means you can also use a fully qualified class name (FQCN) such as mypackage.mysubpackage.MyClass, and the CommandLine will find that class.

Finding the Method
Now that you have the correct class, you have to find the correct method, which is specified as the second word in the command. However, finding the method isn't quite as simple as finding the class. Because Java allows method overloading, a number of different methods can have the same name. The method name isn't enough.

To find the correct method, you need to look at the types of the arguments as well. You can do this with reflection. CommandLine has a method called getTypes that scans a list of arguments contained in an object array and returns an array of classes:

Object args[] = narrow( line, 2 ); Class types[] = getTypes( args );

Wondering what the narrow method is? Narrow takes an array of objects and narrows each one. More specifically, type narrowing is the process of finding the most specific class for an object. When you first get the arguments to the methods, they are string objects. However, some of these strings actually contain integers or floating-point values. Narrow checks each object in the argument array. If it can be parsed correctly as an integer, narrow turns it into an integer. If not, narrow tries to parse it as a floating-point value and, if successful, turns it into a double. Otherwise, it is left as a string.

This allows you to find the most type-appropriate method to call. For example, Calculator.add takes two doubles as arguments. If the user has in fact supplied two doubles on the command line, then you'll be able to find the method called add that takes two doubles as arguments.

Use Class.getDeclaredMethod to find the proper method. This class is part of the Reflection API, and it takes both a method name and an array of method types. If there is an appropriate method, the following will find it:

String methodName = line[1]; try { Method method = class.getDeclaredMethod( methodName, types ); } catch( NoSuchMethodException nsme ) { throw new CommandLineException( "Can't find method "+methodName+" in "+className ); }

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date