Groovy – Getting Started

As promised in the previous entry I am continuing series of Groovy posts. Starting from simple introduction we are moving to intermediate and advanced topics in the future posts.

What is Groovy’s origin?

Everything started in 2003 when James Strachan (official Groovy creator) wrote to Bob McWhirter:

Wouldn’t it be “groovy” if we could have native syntax for lists, maps and regexs in Java like in most scripting languages?

Wouldn’t it by “groovy” if we could have duck typing in Java?

Wouldn’t it be “groovy” if we had closures and properties in Java?

Certainly it would be “groovy” as a result of what we have brilliant scripting language on the JVM.

Groovy is a dynamic language for Java Virtual Machine. It is compiled directly to byte code  which is then executed on the JVM alongside Java byte code. It is one of the main strengths of the language because it uses the same API,  I mean JDK, collections, etc. as Java, has the same security and threading models and finally the same object oriented concepts.

Joint-compilation

Talking about Groovy’s complementary to Java nature joint-compilation term must be mentioned.
Have a look at the following diagram:

java-groovy

Groovy class can implement Java interface and such Groovy class can be extended by another Java class. The same way, Java class can implement Groovy interface and such class can be extended by Groovy class.
Such behavior is possible thanks to joint-compilation. How does it work? Groovy compiler parses the Groovy source files and creates stubs for them, then invokes the Java compiler which compiles the stubs along with Java source files. After that, Groovy compiler continues normal compilation.

Java vs Groovy

Simple class in Java:
public class HelloWorld{

    private String name;

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public String greet(){
        return "Hello " + name;
    }

    public static void main(String[] args){
        HelloWorld helloWorld = new HelloWorld();
        helloWorld.setName("Groovy");
        System.out.println(helloWorld.greet());
    }
}
The same class in Groovy:
public class HelloWorld{

    private String name;

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public String greet(){
        return "Hello " + name;
    }

    public static void main(String[] args){
        HelloWorld helloWorld = new HelloWorld();
        helloWorld.setName("Groovy");
        System.out.println(helloWorld.greet());
    }
}
As you can see, Groovy compiler perfectly compiles Grovy code which is exactly the same as in Java.
So where is the difference? Why Groovy is called “Java on steroids”?
Here is a class doing the same as the one above:
class HelloWorld{

    String name

    String greet(){
        "Hello $name"
    }
 }
def helloWorld = new HelloWorld(name: "Groovy")
println helloWorld.greet()
Now the differences should be clear.
Groovy features based on the above code snippet:
  • everything is public if not stated differently
  • automatic getters and setters
  • semicolons at the end of the line are optional
  • variable interpolation using GStrings
  • return statement is optional; function returns value returned by the last statement
  • dynamic typing using def keyword

Groovy tries to be as natural as possible for Java developers, however there are some differences which should be mentioned and remembered:

  • floating point number literals are BigDecimal type by default
  • Groovy uses default imports which means that the following packages are imported by default:
    • java.io.*
    • java.lang.*
    • java.math.BigDecimal
    • java.math.BigInteger
    • java.net.*
    • java.util.*
    • groovy.lang.*
    • groovy.util.*
  • operator == means equals for all types; if you need to check identity use method is() like object.is(anotherObject)
  • operator in is a keyword
  • array in Java can be declared as follows int[] arr = {1,2,3,4}; but in Groovy we need
    int[] arr = [1,2,3,4] 

 Native syntax for data structures

  • lists
    • def list = [1,’a’]
  • maps
    • def map = [PL:’Poland’, UK:’United Kingdom’] – keys are strings by default
  • ranges
    • def range = 10..15
    • assert range.size() == 6
    • assert range.get(1) == 11
    • assert range instanceof java.util.List

 Operators

Except operators which are common with Java, Groovy supports a list of additional operators:

  • spread operator (*.)
    • used to invoke action on all items of a given aggregate object
    • object*.action which is equivalent to object.coolect{ child->child?.action }
    • assert [‘a’, ‘bb’]*.size() == [1, 2] 
  • Java field (.@)
    • Groovy automatically creates getters for all properties in a class
    • operator allows getting property value directly, without using getter method
    • object.@fieldName
  • Elvis operator (?:)
    • shorter version of Java’s ternary operator
    • ternary operator:
      • def phoneNumber= user.phoneNumber ? user.phoneNumber : “N/A”
    • Elvis operator:
      • def phoneNumber = user.phoneNumber ?: “N/A”
  • safe navigation operator
    • used to avoid NullPointerException
    •  def phoneNumber = user?.phoneNumber
    • if user is null, variable phoneNumber will get null value instead of throwing NullPointerException

 Closures

Closures, one of the “grooviest” features in my opinion. It can be defined as reusable piece of code which can be passed around as it was a string or an integer.

{ println "Hello World!" }

Closures like functions, can get arguments and return values.
 

{ name -> println "Hello $name" }

{ number -> number * number }

Moreover they can be assigned to variables.

def closure = { a,b -> a + b }

Closures can access variables which are in particular closure scope, which is quite obvious. However variables defined within the scope which closure is defined in can be accessed as well.

def CONST = 1

def incrementByConstance = { value -> value + CONST }

println incrementByConstance(5)

Some more closure examples:

square = { it * it } //it - value passed to the closure

[1,2,3,4].collect(square)

 

printMap = { key, value -> println "key=" + key + " value=" + value }

["PL" : "Poland", "UK" : "United Kingdom"].each(printMap)

Stay tuned for further posts regarding Groovy.