脚本包导入实战: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,让规则脚本简洁且无重复导入之虞。对规则脚本可读性有要求的团队,这套别名体系值得纳入规范。

相关推荐
Ivanqhz7 小时前
正余弦位置编码(Sinusoidal Positional Encoding)
java·linux·数据库
BD_Marathon8 小时前
消息对象中字段的说明
java·前端·python
Ai-_Man8 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
Java后端的Ai之路8 小时前
Python进阶探索23 - Python中的Time与Datetime模块
开发语言·数据库·python·datetime·time
zlpzlpzyd8 小时前
nacos的openapi地址
java
沫璃染墨8 小时前
《从零入门Linux系统篇(五十四):线程篇·七——互斥锁底层原理:从原子交换到线程竞争与锁实现》
linux·运维·服务器·开发语言·c++·驱动开发·系统架构
Java后端的Ai之路8 小时前
Python进阶探索24_应用案例_linux系统的监控
linux·开发语言·python·应用·探索
happylifetree9 小时前
Python22-26:核心语法-流程控制语句-if条件判断
python
程序员清风9 小时前
PydanticAI 实战:用类型安全构建可靠的 Python Agent
开发语言·python·安全
落魄实习生9 小时前
Agent Scope Java 2.x 系列【10】Middleware
java·开发语言·ai