脚本包导入实战:JQuick-Java自定义包引入与别名配置教程

脚本包导入实战:JQuick-Java自定义包引入与别名配置教程

前言

规则脚本调用 Java 类型时,写全限定名(java.util.HashMap<java.lang.String,java.lang.String>)不仅冗长还易错。JQuick-Java 提供脚本包导入机制:import 全限定名 as 别名;,一次声明、脚本内短名引用。统一入口 importPackage 更把它变成一行链式调用。本文详解 JQuick-Java 自定义包引入与别名配置的完整用法。

核心技术原理

包导入的语法与解析链路:

  1. 语法层 :文法 importDeclaration: IMPORT paramType AS importVar SEMICOLON;,paramType 支持简单类型、泛型(List<java.lang.String>)、Map/Set/数组等;
  2. 解析层 :JQuickJavaImportVisitor 把 import 语句注册到全局容器 JQuickJavaImportContainerModel(别名 → JQuickJavaTypeReference),脚本内以别名引用类型时按容器解析为真实类型;
  3. 入口层 :importPackage(qualifiedName, alias) 生成 import 全限定名 as 别名; 语句加入包声明列表;importPackage(qualifiedName) 自动取最后一段做别名。

幂等注册是关键:同一 JVM 内重复执行脚本时,registerImports() 检测到别名已存在则跳过,避免「already has been imported」异常。

实战代码演示

1. 基础别名导入

java 复制代码
JQuickJava.create()
        .importPackage("java.lang.String", "type1")   // import java.lang.String as type1;
        .importPackage("java.util.Date", "JDate")     // import java.util.Date as JDate;
        .createApi(ScoringMapper.class, "scoring-rules.xml");

脚本内即可用别名:

jquick 复制代码
type1 def mask(str:name) {
    return type1::valueOf(name);   // 等价 java.lang.String::valueOf
}

2. 自动别名导入

java 复制代码
// 自动取最后一段:java.lang.String → String
JQuickJava.create().importPackage("java.lang.String");

// 批量自动别名
JQuickJava.create().importPackages("java.util.Date", "java.util.Map");

3. 泛型导入(必须显式别名)

jquick 复制代码
// 脚本级语法
import List<java.lang.String> as StringList;
StringList list=["A","B","C"];
java 复制代码
// 入口级 API:含 < 必须指定别名
JQuickJava.create()
        .importPackage("List<java.lang.String>", "StringList")
        .execute("StringList list = [\"A\",\"B\",\"C\"];");

4. 脚本内直接声明 import(JQuickJavaExecutor 路径)

java 复制代码
String rule = "import java.lang.String as string;\n" +
              "import java.lang.System as system;\n" +
              "string def getSquare(int:a,int:b){\n" +
              "    system@out.println(int:a);\n" +
              "    return a+b;\n" +
              "}\n" +
              "int a=2; int b=2;\n" +
              "string c=this.getSquare(int:a,int:b);";
Object result = JQuickJavaExecutor.getInstance().execute(rule);

核心技术细节解析

  • 泛型导入规则 :含 < 的全限定名(List<java.lang.String>)无法自动取别名,importPackage(qualifiedName) 会抛 IllegalArgumentException: generic import requires explicit alias,必须走 importPackage(name, alias)。
  • 别名作用域 :别名在全局导入容器注册(JQuickJavaImportContainerModel.getInstance() 单例),同一 JVM 内跨脚本共享,同名别名以首次注册为准(幂等)。
  • 类型解析 :JQuickJavaTypeReferenceFactory.fromTypeString 优先按类型字符串解析(支持泛型),失败回退 fromClassName 类名加载。
  • 不生成重复 import 行 :buildScript 会检查别名是否已注册,已存在则不生成 import 行,从源头防重复。

常见踩坑与解决方案

  1. 别名冲突:不同脚本对同一类型声明不同别名没问题,但同一别名指向不同类型时,首次注册生效,后续注册被忽略------避免全局别名与业务语义强绑定。
  2. 误用未导入的类型:脚本内引用未 import 的短名类型会解析失败,统一使用全限定名或先 import。
  3. 大小写敏感 :别名与类型名大小写敏感,import java.lang.string(小写 s)无法解析 String。

最佳实践

  • 常用类型(String、Date、List、Map)在入口统一 importPackage,脚本保持短名可读。
  • 泛型类型固定走显式别名,避免每次手写 List<java.lang.String>。
  • 接口级导入集中管理(如 TEmEventScoringServiceTest 的 setUp 中统一导入 str、JDate),保证规则脚本风格一致。

总结

JQuick-Java 的脚本包导入机制,用 import Type as Alias; 把全限定类型名收敛为短名:普通类型自动别名、泛型显式别名、全局容器幂等注册,配合入口 importPackage 链式 API,让规则脚本简洁且无重复导入之虞。对规则脚本可读性有要求的团队,这套别名体系值得纳入规范。

相关推荐
承渊政道9 小时前
【Python编程—从入门到实践】(记分与闯关:用Python+Pygame,打造越战越精彩的太空大战!)
开发语言·python·pycharm·游戏程序·pygame
爱学习的程序媛9 小时前
Python常用框架梳理
开发语言·后端·python·ai·web·后端框架·python框架
imgsq9 小时前
GESP Python 一到四级:备考路线与真题特点
python·青少年编程
budingxiaomoli10 小时前
Spring统一功能处理
java·后端·spring
eggwyw11 小时前
Anaconda安装卸载的详细流程指南
开发语言·python
2601_9679791211 小时前
纯手写:Python安装pip完整教程,搞了几小时,终于成功
python·教程·pip·安装·包管理
Norna11 小时前
缓存文件从没写出来:一个 .json 被当成目录用了
python
Flynn Liang12 小时前
可观测性与成本治理:一次对话的 17 个观测点
java·langchain·可观测性·micrometer·langchain4j·token 成本·llm 监控
金銀銅鐵12 小时前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
aifannihao14 小时前
AI 学习第 14 课:CNN 训 6 轮卡在 0.5352,数据没打乱
pytorch·python·深度学习·cnn·学习路线