System.out.println("java.version="+System.getProperty("java.version"));
System.out.println("java.runtime.name="+System.getProperty("java.runtime.name"));
ScriptEngine jshell = new JShellScriptEngine();
Bindings b = jshell.createBindings();
jshell.setBindings(b, ScriptContext.GLOBAL_SCOPE);
jshell.setBindings(b, ScriptContext.ENGINE_SCOPE);
long start = System.nanoTime();
jshell.eval("long kk = 0L; for(int i=0; i<100000000; i++) kk += i; System.out.println(\"kk=\"+kk); 20;");
double duration = (System.nanoTime()-start)*1e-9;
System.out.println("duration="+duration+" loopBodiesPerSec="+(1e8/duration));
Object xy = jshell.eval("class PairXY{ public final int x, y; public PairXY(int x, int y){ this.x = x; this.y=y; } public Object theT(){ return 9.87; } } Class PairXYClass = PairXY.class;");
System.out.println("PairXYClass: "+jshell.eval("PairXYClass"));
System.out.println("xy = "+xy);
System.out.println("xy.getClass() = "+xy.getClass());
Object mmB = jshell.eval("Object mmB = PairXYClass.getConstructor(int.class,int.class).newInstance(55,66);");
System.out.println("mmB = "+mmB);
System.out.println("mmB.getClass() = "+mmB.getClass());
double calledTheTByReflection = (Double) mmB.getClass().getMethod("theT").invoke(mmB);
System.out.println("calledTheTByReflection = "+calledTheTByReflection);
Outputs this...
java.version=11.0.2
java.runtime.name=OpenJDK Runtime Environment
kk=4999999950000000
duration=0.523169 loopBodiesPerSec=1.9114282382939357E8
PairXYClass: class REPL.$JShell$3$PairXY
xy = class REPL.$JShell$3$PairXY
xy.getClass() = class java.lang.Class
mmB = REPL.$JShell$3$PairXY@55b62629
mmB.getClass() = class REPL.$JShell$3$PairXY
calledTheTByReflection = 9.87
If "new PairXY(2,3)" is in the first eval, it works, but not if its in the second later evals. So I put its Class object in a jshell var so the later evals could see it and use by reflection, and it works, as you see theT called which returns 9.87.
Is there an easier way to keep classes across evals?
System.out.println("java.version="+System.getProperty("java.version")); System.out.println("java.runtime.name="+System.getProperty("java.runtime.name")); ScriptEngine jshell = new JShellScriptEngine(); Bindings b = jshell.createBindings(); jshell.setBindings(b, ScriptContext.GLOBAL_SCOPE); jshell.setBindings(b, ScriptContext.ENGINE_SCOPE); long start = System.nanoTime(); jshell.eval("long kk = 0L; for(int i=0; i<100000000; i++) kk += i; System.out.println(\"kk=\"+kk); 20;"); double duration = (System.nanoTime()-start)*1e-9; System.out.println("duration="+duration+" loopBodiesPerSec="+(1e8/duration)); Object xy = jshell.eval("class PairXY{ public final int x, y; public PairXY(int x, int y){ this.x = x; this.y=y; } public Object theT(){ return 9.87; } } Class PairXYClass = PairXY.class;"); System.out.println("PairXYClass: "+jshell.eval("PairXYClass")); System.out.println("xy = "+xy); System.out.println("xy.getClass() = "+xy.getClass()); Object mmB = jshell.eval("Object mmB = PairXYClass.getConstructor(int.class,int.class).newInstance(55,66);"); System.out.println("mmB = "+mmB); System.out.println("mmB.getClass() = "+mmB.getClass()); double calledTheTByReflection = (Double) mmB.getClass().getMethod("theT").invoke(mmB); System.out.println("calledTheTByReflection = "+calledTheTByReflection);
Outputs this...
java.version=11.0.2 java.runtime.name=OpenJDK Runtime Environment kk=4999999950000000 duration=0.523169 loopBodiesPerSec=1.9114282382939357E8 PairXYClass: class REPL.$JShell$3$PairXY xy = class REPL.$JShell$3$PairXY xy.getClass() = class java.lang.Class mmB = REPL.$JShell$3$PairXY@55b62629 mmB.getClass() = class REPL.$JShell$3$PairXY calledTheTByReflection = 9.87
If "new PairXY(2,3)" is in the first eval, it works, but not if its in the second later evals. So I put its Class object in a jshell var so the later evals could see it and use by reflection, and it works, as you see theT called which returns 9.87.
Is there an easier way to keep classes across evals?