Search code examples
groovycastingoperator-precedenceelvis-operator

Elvis operator and type casting precedence in Groovy


Let's take the following simple expression:

((Double) null ?: 0).getClass()

Results:

  • Groovy 3: class java.lang.Double
  • Groovy 4: class java.lang.Integer

Does anyone know the reason for the different behaviour? I'd say Groovy 4 is correct since the casting is applied before the Elvis operator.

Checked, but couldn't find anything related in the Groovy 4 release notes: https://groovy-lang.org/releasenotes/groovy-4.0.html


Solution

  • From the docs the precedence of the ?: is much lower than typecast. Typecast (type) is level 1 precedence and the elvis operator ?: is 14 so it looks like Groovy 4 is doing the right thing.

    https://groovy-lang.org/operators.html#_operator_precedence

    and in Groovy 3 docs it is documented the same:

    http://docs.groovy-lang.org/docs/groovy-3.0.18/html/documentation/#_operator_precedence

    The only way I might explain it is simple bug in Groovy 3 that went unnoticed, or maybe a bug that was fixed in later versions of Groovy 3 depending on the version you're using to test it. It might be worth it to report it even though its fixed just so they could write a unit test to catch it in the future since it possibly went unnoticed.