SpEL - 空值比较

Soc*_*tes 5 spring spring-el

我正在尝试将 spring 版本从 3.0.5 升级到 3.2.11。

当表达式比较空值时,我遇到了 SpEL 的麻烦,如下所示:

new SpelExpressionParser().parseExpression("null < 7").getValue();    
Run Code Online (Sandbox Code Playgroud)

上述代码的结果是

  • false,使用版本 3.0.5 时
  • 是的,当使用版本 3.2.11 时,这是不正确的,因为我认为

这种不同行为的原因是在 SpEL 内部使用的 StandartTypeComparator 类中,compare 方法有不同的实现:

  • 版本3.0.5

    public int compare(Object left, Object right) throws SpelEvaluationException {
    // If one is null, check if the other is
    if (left == null) {
        return right == null ? 0 : 1;
    } else if (right == null) {
        return -1; // left cannot be null
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 版本3.2.11

    public int compare(Object left, Object right) throws SpelEvaluationException {
    // If one is null, check if the other is
    if (left == null) {
        return right == null ? 0 : -1;
    } else if (right == null) {
        return 1; // left cannot be null
    }
    
    Run Code Online (Sandbox Code Playgroud)

当我观察上面的代码时,我可以看到正在运行

new SpelExpressionParser().parseExpression("7 < null").getValue();    
Run Code Online (Sandbox Code Playgroud)

将导致:

  • 是的,当使用版本 3.0.5 时,这是不正确的,因为我认为
  • false,使用版本 3.2.11 时

这基本上意味着交换比较逻辑和行为的重大变化,并对我们的应用程序产生重大影响。

可能存在概念问题 - 当比较两个值时,假设它们具有可比性,它们可以等于、小于或大于另一个值。但从这个意义上说,空值与除了空值之外的任何东西都没有可比性,对吗?

这是一个错误吗?

使用 <、>、==、<=、>= 运算符与另一个非空值进行比较时,空值比较是否被认为是 TRUE?

Ton*_*ony 2

这不是一个错误,这是 Spring 团队的设计行为。

来自Spring 文档

与 null 的大于/小于比较遵循一个简单的规则:null 在这里被视为无(即不为零)。因此,任何其他值始终大于 null(X > null 始终为 true),并且任何其他值都不会小于空(X < null 始终为 false)。

如果这种行为影响你的逻辑,我认为你可以这样做:

 " first == null ? false : second == null ? false : first < second "
Run Code Online (Sandbox Code Playgroud)