【问题标题】:Operator overloading/definition for custom classes in Jexl3Jexl3 中自定义类的运算符重载/定义
【发布时间】:2017-09-20 15:17:14
【问题描述】:

我正在尝试实现一个在 Jexl 表达式中表现得像 Boolean 的自定义类:

示例: Object result = jexl.createExpression("a || b").evaluate(context)

其中a 和b 是自定义类的实例,其中包含boolean 和应通过评估表达式携带的额外信息,以便最终可以在result 中访问它。

我已经读到 Jexl3 应该支持运算符重载,并且它似乎具有为自定义类定义自己的运算符的所有必要结构 - 但是我无法理解这样做需要哪些步骤。

我已经尝试通过自定义实现扩展Uberspect 和JexlArithmetic,但是我只发现使用toBoolean 我可以将我的自定义对象转换为Boolean(这使得result 成为Boolean -因此我丢失了所有额外的信息)。

如何正确使用/扩展 Jexl 为自定义类提供布尔运算符?

【问题讨论】:

    标签: java operator-overloading jexl


    【解决方案1】:

    只需扩展 JexlArithmetic 类并覆盖内部的 or 方法。

    public class ExtendedJexlArithmetic extends JexlArithmetic
    {
        public Object or(YourCustomClass left, YourCustomClass right)
        {
                return left.or(right); // make sure you've implemented 'or' method inside your class
        }
    }
    

    然后在下面尝试:

    JexlContext jexlContext = new MapContext();
    
    jexlContext.set("a", new YourCustomClass());
    jexlContext.set("b", new YourCustomClass());
    
    JexlEngine jexlEngine=new JexlBuilder().arithmetic(new ExtendedJexlArithmetic (true)).create();
    
    System.out.println(jexlEngine.createScript("a | b").execute(jexlContext);
    

    【讨论】:

    • 我花了一些时间才弄清楚为什么这个例子有效而我的无效。您的解决方案是在按位运算符中实现布尔逻辑的解决方法。因此,您正在评估a | b 而不是a || b,因为我们通常会用Java 编写它。这是一种解决方法,除非您需要在 jexl 代码中进行按位操作,否则该解决方法才有效。当然,完全禁止使用布尔运算符|| 和&&!
    • @JMax 是的,你可以使用 '|'但不是'||',如'||'不是 JEXL 中的有效运算符。
    • 不幸的是,我不得不说你的方法看起来不错,但最终它不起作用,仅仅是因为缺少一个基本的布尔运算:not 或!。在那里我强烈建议大家不要遵循这种方法:(
    • @JMax 它确实有 - 或 negate(x) 用于否定。见这里:commons.apache.org/proper/commons-jexl/apidocs/org/apache/…
    • Jexl 有,但不能与使用| 而不是|| 的变通方法结合使用。如果您使用not,Jexl 会在内部将对象转换为boolean,并且所有额外信息都消失了——这正是默认行为以及我创建此问题的原因。结论:JEX 根本无法用于该场景它不起作用!
    【解决方案2】:

    【讨论】:

    • 感谢您的信息。然而,|| 和 && 之类的布尔逻辑似乎没有被 Arithmetic 实现所涵盖。运算符重载仅适用于数字,不适用于布尔逻辑。而且我不能添加新的运算符,因为JexlOperator 是一个不能被子类化的枚举。
    • 你是对的,我忽略了'||';不幸的是,在这个阶段不能重载短路运算符,懒惰的第二个参数评估使实现和签名变得相当复杂。解决方法是使用 / 重载 '|'和'&'。
    猜你喜欢
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多