Search code examples
javagroovydynamic

Groovy If condition vs Java's if condition


When I run this code in Groovy, it runs successfully. It even compiles successfully using groovyc.

if (2<3 || a_variable_not_defined_anywhere) {
  println "This is still working"
}

This prints out the output same as print statement. I understand that when first condition in "or" condition is successful, it will not even check the second condition.

But a similar "If" structure in Java errors out saying that variable is not defined.

My question is why it is running in Groovy and not in Java? When both are compiled languages. Even in Python the above "If" structure works, but Python is Interpreted in nature. Or does this have to do with the fact that both Groovy and Python are Dynamic in nature?

Can someone please clarify this? Thanks

Update: With respect to bindings, I tried this code:

if (2<3 || a_variable_not_defined_anywhere) {
  println "This is still working"
}
a = 2
println binding.variables

This actually printed "a" as binding variables but not "a_variable_not_defined_anywhere"

So not sure it has anything to do with bindings here.


Solution

  • In Groovy script the variable a_variable_not_defined_anywhere could be defined at runtime in binding.variables (see binding). The binding context for the script is determined at runtime, therefore it compiles. At runtime, the second condition of the or statement is not executed, as already mentioned.

    The point is that you could inject the variable before executing the script. In Java, there is no binding. So the compiler knows already at compile time that something's off and throws an exception.

    EDIT: Hopefully, this example makes it a bit clearer than the one before:

        // Let's say this is your code:
        String code = "println(a)"
        // Variable "a" is not defined, but the code compiles
        // in Groovy, because "a" could exist at runtime
      
        def sh = new GroovyShell(this.class.classLoader, new Binding([a: "Hello World"]))
        // Here, "a" exists at runtime -> the code runs just fine.
        sh.evaluate(code)
    
        def shRuntimeError = new GroovyShell(this.class.classLoader, new Binding([:]))
        // Here, "a" does not exist at runtime -> throws MissingPropertyException.
        shRuntimeError.evaluate(code)