如何在JShell的eval传入字符串内部嵌套调用eval执行动态代码
JShell 嵌套调用 eval 可行解决方案
JShell 实现方案
核心逻辑:将宿主端创建的JShell实例作为全局变量注入到JShell自身的执行上下文,内部代码即可调用该实例的eval方法实现嵌套执行。
完整示例代码
import jdk.jshell.JShell; public class JShellNestedEval { public static void main(String[] args) { // 创建JShell实例 JShell jsh = JShell.create(); // 预先导入JShell相关包,简化后续代码 jsh.eval("import jdk.jshell.*;"); // 注入当前JShell实例到执行上下文,变量名设为currentJShell jsh.eval("JShell currentJShell = " + jsh + ";"); // 可选:封装顶层eval方法,实现和Python/JS一致的调用写法 jsh.eval(""" void eval(String code) { currentJShell.eval(code); } """); // 测试嵌套调用,完全符合期望的写法 jsh.eval(""" // 直接调用封装好的eval eval("int j = 4;"); System.out.println(j); // 输出4,证明变量已生效 // 支持循环内动态执行代码,完全替代无法生效的/open命令 for(int c=0;c<3;c++){ eval("System.out.println(\"循环执行第\" + " + c + " + \"次\");"); } """); // 外层上下文可正常访问内部eval定义的变量 jsh.eval("System.out.println(\"外层访问内部变量j:\" + j);"); jsh.close(); } }
注意事项
- 依赖Java 9及以上版本,JShell为JDK自带模块无需额外引入依赖
- 所有通过嵌套
eval执行的代码,变量、方法定义都会共享到同一个JShell上下文,内外层可互相访问
C# Script 实现方案
和JShell逻辑一致,将脚本引擎的执行方法注入到全局上下文即可:
using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; // 定义全局变量承载类 public class ScriptGlobals { public Func<string, Task<object>> eval; } public class CSharpNestedEvalDemo { public static async Task Main(string[] args) { var globals = new ScriptGlobals(); // 绑定eval方法到全局变量 globals.eval = async (code) => await CSharpScript.EvaluateAsync(code, ScriptOptions.Default, globals); // 测试嵌套调用 await globals.eval(@" eval(""int j = 4;""); Console.WriteLine(j); // 输出4 for(int c=0;c<3;c++){ eval($""Console.WriteLine($"循环第{c}次")""); } "); } }
内容的提问来源于stack exchange,提问作者Maj
相关产品推荐
相关产品推荐

