I've written simple test in Groovy
using Spock framework
class SimpleSpec extends Specification {
def "should add two numbers"() {
given:
final def a = 3
final b = 4
when:
def c = a + b
then:
c == 7
}
}
Variable a
is declared using def
and final
keywords combination. Variable b
is declared using only final
keyword.
My question is: what's the difference (if any) between these two declarations? Should one approach be preffed to the other? If so, why?
User daggett ist right, final
does not make a local variable final in Groovy. The keyword only has influence on class members. Here is a little illustration:
package de.scrum_master.stackoverflow
import spock.lang.Specification
class MyTest extends Specification {
def "Final local variables can be changed"() {
when:
final def a = 3
final b = 4
final int c = 5
then:
a + b + c == 12
when:
a = b = c = 11
then:
a + b + c == 33
}
final def d = 3
static final e = 4
final int f = 5
def "Class or instance members really are final"() {
expect:
d + e + f == 12
when:
// Compile errors:
// cannot modify final field 'f' outside of constructor.
// cannot modify static final field 'e' outside of static initialization block.
// cannot modify final field 'd' outside of constructor.
d = e = f = 11
then:
d + e + g == 33
}
}
When I switched one of my Spock projects to version 1.3 with Groovy 2.5 and noticed that this test no longer compiles now due to the compiler detecting the reassignment to final local variables. I.e. the inconsistency in Groovy <= 2.4 seems to be fixed.