3

This code in Java:

for (Integer x=1; x <= 3; x++) {
    y = "array[" + Integer.toString(x) + "] = a" + Integer.toString(x) + ".getText();";
    System.out.println(y);
    }

prints out:

array[1] = a1.getText();
array[2] = a2.getText();
array[3] = a3.getText();

However, instead of having string y printed out I want it executed. How do I do this in Java?

If this is not possible, is there another way to achieve what I want, different from using the 3 instructions?

array[1] = a1.getText();
array[2] = a2.getText();
array[3] = a3.getText();

For simplicity I have used 3 although I need 20 instructions. More importantly, I am trying to learn more about Java and am looking for a more elegant solution.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Jan Nordgreen
  • 55
  • 1
  • 10

4 Answers4

1

What you're looking for is "eval" in many interpreted languages. Java does not allow you to eval source code at run time. This is a property of being a compiled rather than interpreted language.

You can get some of the functionality through reflection or bytecode generation, but these are advanced features usually used by people developing frameworks or libraries, not a routine part of everyday programming.

Kevin Peterson
  • 7,189
  • 5
  • 36
  • 43
  • 1
    "Does not allow" is a bit strong, given the ability to compile source code at runtime. – Andy Thomas Feb 23 '13 at 16:28
  • +1 for reflection. If the problem is with pulling identically typed, similarly named, but not indexed, variables from an object, reflection is the way. – Seva Alekseyev Feb 23 '13 at 19:09
1

Although Java itself is not a scripting language, it does have a library, javax.script, that supports scripts with an eval method. I've used it when I wanted to allow an expression as an input parameter to a program.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Examples can be seen [here](http://stackoverflow.com/a/8162055/418556) & [here](http://stackoverflow.com/a/6426684/418556) & [here](http://stackoverflow.com/a/7441804/418556).. – Andrew Thompson Feb 23 '13 at 16:37
0

Simple loop can do your job :

for(int i=0;i<array.length;i++){
array[i] = a[i].getText();
}
Arpit
  • 12,767
  • 3
  • 27
  • 40
0

Choices:

  1. you can call the java compiler from java, create a class, and call it dynamically. This is overkill for a few line snippet.

  2. if your "20 instructions" are all of a similar form, and you have a finite vocabulary, then you could create your own "instruction set" and key off of that with some dispatch function. (This is a generic solution for any language.)

  3. if you've used to more powerful languages like Lisp, some of the available scripting languages for java also have an eval function.

I like groovy because it has the best of both worlds: dynamic and functional use, closures, interactive, exploratory (eg tab completion on vars and methods), and is a superset of the java language and can use all of your existing java classes and jars. Easy to embed a groovy console to popup (even from your server) and interactively poke around, examine values, etc.

Below is an example of evaluating the code from the groovy shell; calling it from Java is practically the same; see http://groovy.codehaus.org/Embedding+Groovy

$ groovysh
Groovy Shell (1.8.4, JVM: 1.6.0_24)
Type 'help' or '\h' for help.
---------------------------------------------------------------------------------------------
groovy:000> class Athing {  String name; public Athing(String name){ this.name=name; }; String getText() { return name + "'s getText() returns..."; }; }
===> true
groovy:000> a1 = new Athing("a1"); a2 = new Athing("a-two");  a3 = new Athing("A_3"); 
===> Athing@6e7616ad
groovy:000> a1.getText()        // showing 
===> a1's getText() returns...
groovy:000> b = new Binding();
===> groovy.lang.Binding@2c704cf5
groovy:000> array = [ 'not','set','yet' ]   // create an array for return values
===> [not, set, yet]
groovy:000> b.setVariable( "a1", a1 ); b.setVariable( "a2", a2 ); b.setVariable( "a3", a3 ); b.setVariable( "array", array );
===> null
groovy:000> shell = new GroovyShell(binding);
===> groovy.lang.GroovyShell@24fe2558
groovy:000> code = "array[1] = a1.getText();\n" + "array[2] = a2.getText();\n" + "array[3] = a3.getText();\n";
===> array[1] = a1.getText();
array[2] = a2.getText();
array[3] = a3.getText();

groovy:000> array                        // value of array before
===> [not, set, yet]
groovy:000> shell.evaluate( code );      // evaluate the string of code we were given
===> A_3's getText() returns...
groovy:000> array
===> [not, a1's getText() returns..., a-two's getText() returns..., A_3's getText() returns...]
groovy:000> 
toddkaufmann
  • 315
  • 2
  • 10