2. What is Groovy
• Powerful, object oriented, and dynamic language (has features similar to other
popular dynamic languages like Python, Ruby and Smalltalk)
• Groovy is optionally typed
• Has static-typing and static compilation capabilities, for the Java platform aimed at
improving developer productivity
• Targeted for JVM – gets compiled to Java bytecode at runtime.
• Integrates smoothly with any Java program and libraries
• Very suitable for scripting though not limited to scripting.
A multi-faceted language for the Java platform
JVM
Java Scala Groovy Clojure Jython
CLR (.NET)
VB F# IronPythonC# IronRuby
Popular Language Virtual Machines
3. A bit of history
• August 2003 - James Strachan first talked about the development of Groovy
• b/w 2004 and 2006 - Several versions were released
• January 2007 - After the JCP standardization process began, the version
numbering changed and a version called "1.0" was released on.
… various betas and release candidates numbered
• December 2007 - Groovy 1.1 Final was released and immediately rebranded as
Groovy 1.5 as a reflection of the many changes made.
• November 2008 - SpringSource acquired the Groovy and Grails company (G2One).
In August 2009 VMWare acquired SpringSource
• July 2012 - Groovy 2.0 was released. Added static compilation and a static type
checker to Groovy.
• April 2013 - Groovy and Grails formed part of Pivotal (JV b/w EMC and VMware)
product portfolio.
• April 2015 - Pivotal ceased sponsoring Groovy and Grails from April 2015. Groovy
submitted to become a project at The Apache Software Foundation
4.
5.
6. • Groovy has gained quite a
lot of popularity in recent
times and have raised to
17th spot from 36th spot in
an year
• Most popular alternate to
Java on JVM platform
http://www.tiobe.com/tiobe_index
7. First program
• Groovy programs do not need a main entry point, as required in Java
• No need to explicitly specify System.out.println – only println is sufficient
println("Hello Groovy")
• Method calls can omit the parentheses if there is at least one parameter and there
is no ambiguity – so the program could be further simplified to
println "Hello Groovy"
9. Comments
• Single line comment
// this would print Hello Groovy to console
println("Hello Groovy")
• Multi line comment
/* This is
an example of
multiline comment */
println("Hello Groovy")
• Shebang line - understood by UNIX systems which allows scripts to be run directly
from the command-line.
#! single line comment in the format of shebang line
println "Hello from the shebang line"
# must be the first character of the file. Any indentation would yield a compilation error.
10. Variables and Type Inference
• Declared with explicit type declaration
int no = 1
bool isTodayHoliday = true
float salary = 1234.567
String message = "Hello World"
• Declared without any type declaration using def (type is inferred)
def no = 1 // implicitly typed to Integer
def isTodayHoliday = true // implicitly typed to Boolean
def salary = 1234.567 // implicitly typed to BigDecimal
def message = "Hello World“ // implicitly typed to String
11. Constants
• Declared with explicit type declaration
const PI = 3.14
println PI
PI = 3.17 // does not compile and throws a compile time error
12. Types
• Groovy supports the same primitive types as those defined by the Java Language
Specification
• Integral types - byte (8 bit), short (16 bit), int (32 bit) and long (64 bit)
• Floating point types - float (32 bit) and double (64 bit)
• boolean (true, false)
• char - 16 bit, usable as a numeric type, representing an UTF-16 code
• Primitive types are represented as wrapper classes (java.lang)
Primitive type Wrapper class
boolean Boolean
char Character
short Short
int Integer
long Long
float Float
double Double
def x = 10
println x
println x.getClass()
// class java.lang.Integer
13. Dynamic typing
• In contrast to statically typed languages like Java, C#, Groovy is a dynamically
typed language (like JavaScript) that supports dynamic typing
def x = 10 // integer
println x
x = "Hello World" // string
println x
x = true // boolean
println x
x = 123.4567 // double
println x
14. Strings
• Single quoted string – represents java.lang.String objects, does not support
interpolation
• Double quoted string – represents java.lang.String objects or
groovy.lang.Gstring (which supports interpolation). If interpolation is not used
then java.lang.String is used, otherwise groovy.lang.Gstring is used.
• Triple quoted string – allows multiline strings
def (name, org) = ["RK", "Mphasis"]
// same as def name = "RK"; def org = "Mphasis"
println("My name is ${name} and I work for ${org}")
println("My name is ${name} and I work for ${org}")
println('My name is ${name} and I work for ${org}')
My name is RK and I work for Mphasis
My name is RK and I work for Mphasis
My name is ${name} and I work for ${org}
15. String Interpolation
• Any Groovy expression can be interpolated in all string literals, apart from single
and triple single quoted strings.
• Interpolation is the act of replacing a placeholder in the string with its value upon
evaluation of the string.
• The placeholder expressions are surrounded by ${} or prefixed with $ for dotted
expressions.
def name = "Bill"
def age = 25
println("Name - $name , Age - $age")
println("2 + 3 = ${2 + 3}") // prints 2 + 3 = 5
def person = [name:"Bill",age:25]
println("Name - $person.name, Age - ${person.age + 1}")
// prints Name - Bill, Age - 26
16. Array
• Any Groovy expression can be interpolated in all string literals, apart from single
and triple single quoted strings.
• Interpolation is the act of replacing a placeholder in the string with its value upon
evaluation of the string.
• The placeholder expressions are surrounded by ${} or prefixed with $ for dotted
expressions.
String[] cities = ['Kolkata','Bangalore','Amsterdam']
println(cities)
println(cities.getAt(1)) // prints Bangalore
println(cities[1]) // prints Bangalore
println(cities instanceof String[]) // prints true
println(cities.length) // prints 3
println(cities.size()) // prints 3
17. if else
• Similar to Java
def age = 10
if (age >= 18 && age <= 60) {
println "You can vote, you have to stand in a queue"
}
else if (age > 60) {
println "You can vote but no need to stand in a queue"
}
else {
println "You cannot vote"
}
• Braces could be removed for single statement
if (age >= 18 && age <= 60)
println "You can vote, you have to stand in a queue"
else if (age > 60)
println "You can vote but no need to stand in a queue"
else
println "You cannot vote"
18. if else
• It’s possible to specify it in a single line –
def age = 20
if (age >= 18 && age <= 60) println "Can vote, come in queue"
else if (age > 60) println "Can vote right away"
else println "Cannot vote"
19. Turnery operator (elvis)
• Supports Turnery operator similar to Java –
def isFTE = false
def salary = isFTE == true ? 100 : 75
println salary // prints 75
• For value assignment checking null elvis operator ?: could be used
def defaultSalary
def salary = defaultSalary ?: 75
println salary // prints 75
defaultSalary = 150
salary = defaultSalary ?: 75
println salary // prints 150
20. switch
// Employee Type
// 1 = FTE,
// 2 = Contractor,
// 3 = Retired
def employeeType = 2
switch (employeeType) {
case 1:
println "You are FTE"
break
case 2:
println "You are Contractor"
break
case 3:
println "You are Retired"
break
}
// Employee Type - FTE, Contractor,
// Retired
def employeeType = "Retired"
switch (employeeType) {
case "FTE":
println "You are FTE"
break
case "Contractor":
println "You are Contractor"
break
case "Retired":
println "You are Retired"
break
}
• Java switch statements could be used for int only (or for byte , char and short that
gets converted to int when used for switch), Java 7 allows switching strings
• Groovy switch statements are more flexible than Java
21. switch (cont’d)
• Not only String, Int other types like enum also could be used in switch
enum Employees {
FTE, Contractor, Retired
}
def emp = Employees.FTE
switch (emp) {
case Employees.FTE:
println "You are a FTE"
break
case Employees.Contractor:
println "You are a Contractor"
break
case Employees.Retired:
println "You are Retired"
break
default:
println "Can not decide employee type"
}
22. while
• Groovy supports the usual while {…} loops like Java
• Groovy does not support do while
def ctr = 0
while (ctr < 5) {
println ctr
ctr++
}
23. for in loop
• Similar to Java for each
// primeNos is a list of single digit prime numbers
// List are similar to Arrays, but more powerful
def primeNos = [1,3,5,7]
for (no in primeNos){
println no
}
• Braces could be removed for single statement
def cities = ['Bangalore','Kolkata','London','Paris']
for (city in cities)
println city
24. Classical for loop
• Similar to Java for
for(int ctr=0;ctr<5;ctr++) {
println ctr
}
• Braces could be removed for single statement
for(int ctr=0;ctr<5;ctr++)
println ctr
25. Methods (Functions)
• A method is defined with a return type or with the def keyword, to make the return
type untyped.
• A method can also receive any number of arguments, which may not have their
types explicitly declared.
• Java modifiers can be used (public, private, protected) normally, and if no visibility
modifier is provided, the method is public.
// method declaration
def sayHello() {
println "Hello"
}
// method invokation
sayHello()
// Removing parenthesis for parameterless methods are not allowed
sayHello // this would not compile
// Java way ...
void sayHello(){
println "Hello"
}
26. Methods (cont’d)
// method declaration
def sayHello() {
println "Hello"
}
// method invokation
sayHello()
// Removing parenthesis for parameterless methods are not allowed
sayHello // this would not compile
27. Methods
// smilimar to Java, C
int add(int num1, int num2) {
return num1 + num2
}
// similar to dynamic languages
def sub(num1, num2) {
num1 - num2
}
// could be further shortended to
def mul(num1, num2) { num1 * num2 }
println(add(20, 10)) // 30
println(sub(20, 10)) // 10
println(mul(20, 10)) // 200
28. Methods – Named & Default Arguments
• Default arguments make parameters optional. If the argument is not supplied, the
method assumes a default value.
def add(i = 10, j = 20){
i+j
}
println(add()) // 30
println(add(200, 100)) // 300
println(add(100)) // 120
println(add(j=300, i = 200)) // 500
println(add(i=300)) // 320
29. Methods – varargs
• Groovy supports methods with a variable number of arguments.
• Denoted by … parameter name
def printMessage(message, ... props){
println message
println props
println props.length
}
printMessage("Hello")
printMessage("Hello","Arg1","Arg2")
printMessage("Hello",["Arg1","Arg2","Arg3","Arg4"])
30. Optionality (Low ceremony, Less friction)
• Optional parentheses - Method calls can omit the parentheses if there is at least
one parameter and there is no ambiguity
println 'Hello World'
println(Math.max(5, 10)) // parentheses are required here
• Optional Semicolon - Semicolons at the end of the line can be omitted, if the line
contains only a single statement.
String msg = "Hello"; def ctr = 10
• Optional return - the last expression evaluated in the body of a method or a closure
is returned. This means that the return keyword is optional.
• Optional public keyword - By default, Groovy classes and methods are public,
compared to private in Java
31. return statement is optional
• Single line comment
def add(num1, num2){
num1 + num2 // same as return num1 + num2
}
println(add(20,10)) // prints 30
33. Range
• Allows creating a sequence of values - influenced by Range type in Python which
behaves almost identical to Groovy Range. Not supported in Java.
• These can be used as List since Range extends java.util.List.
• Are specified using the double dot .. range operator between the left and the right
bound.
def nos = 1 .. 10 // 1 is left bound, 10 is right bound
println(nos) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
• The ..< range operator specifies a half-exclusive range--that is, the value on the
right is not part of the range
def nos = 1 .. <10 // 1 is left bound, 9 is right bound
println(nos) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
• The range operator along with for in loop could be used for quick traversal
for (x in 1..5)
println(x)
34. Range (cont’d)
• Could be used for other types also, not only numeric types
def chars = 'a'..'g'
println(chars) // [a, b, c, d, e, f, g]
• Supports methods like size(), get(index), contains(value) etc
def nos = 1..10
println(nos.size()) // 10
println(nos.getAt(2)) // 3
println(nos[2]) // 3
println(nos.contains(2)) // true
println(nos.contains(12)) // false
35. List
• Lists are similar to Array, but is more flexible. List is an ordered collection of objects.
• Each list expression creates an implementation of java.util.List.
nos = [1,3,5,7]
println(nos) // prints [1,3,5,7]
• List elements could be accessed and updated using index
println(0) // prints 1 – index is 0 based
println(1) // prints 3
println(-1) // prints 3
println(-2) // prints 5
nos[0] = 11 // updates first or 0th element to 11
println(nos) // prints [11,3,5,7]
nos[1..3] = [13,15,17] // updates first or 0th element to 11
println(nos) // prints [11,13,15,17]
36. List
• Lists can contain elements of different types
nos = [1,3,5,7,'Kolkata','Bangalore']
• Elements could be added using +=
nos += [50,true,100,"Minneapolis"]
println(nos) // [1, 3, 5, 7, Kolkata, Bangalore, 50, true, 100, Minneapolis]
• Elements could be added using -=
nos -= ['Kolkata','Minneapolis','Bangalore',true]
println(nos) // [1, 3, 5, 7, 50, 100]
• Even * operator works with Lists
alph = ['a','c']
println(alph * 2) // [a,c,c,a]
println(alph * 3) // [a,c,c,a,a,c]
37. List
• Lists can contain elements of different types
def primes = []
primes.add(1)
primes.add(3)
primes.add(5)
println primes[1] // prints 3
println(primes.get(2)) // prints 5
println(primes.getAt(2)) // prints 5
primes[2] = 7
println primes[2] // prints 7
38. Map
• Collection that stores the key value pairs
• Maps store and retrieve values by key, whereas lists retrieve them by numeric
index.
• Called Dictionaries in some other languages.
def designations = [
11 : 'SVP',
10 : 'VP',
9 : 'AVP',
8 : 'Sr. Manager',
7 : 'Manager'
]
println designations[10] // prints VP
designations[10] = 'Vice President'
println designations[10] // prints Vice President
39. Map
• Keys can be strings also, need not only be int
def capitals = [
'IN' : 'New Delhi',
'USA' : 'Washington',
'UK' : 'London'
]
println capitals['IN'] // prints New Delhi
capitals['USA'] = 'Washington DC'
println capitals['USA'] // prints Washington DC
println capitals.size() // prints 3
40. Map
• Has methods to write and read key, value pairs.
def statusCodes = [:]
statusCodes.put(200,'OK')
statusCodes.put(400,'Bad Request')
println statusCodes.get(200)
41. Collection methods
• Has methods to write and read key, value pairs.
def languages = ['Java','Python','C#','Groovy']
println(languages.reverse()) // [Groovy, C#, Python, Java]
println(languages.sort(false)) // [C#, Groovy, Java, Python]
println(languages.contains('Ruby')) // false
println(languages.containsAll('Java','Groovy')) // true
42. Class
• Groovy classes are very similar to Java classes, compatible at JVM level.
• They may have methods and fields/properties, which can have the same modifiers
(public, protected, private, static, etc) as Java classes.
• Groovy classes are bit different from their Java counterparts -
• Public fields are turned into properties automatically, which results in less verbose code,
without so many getter and setter methods.
• Their declarations and any property or method without an access modifier are public.
• Classes do not need to have the same name of the files where they are defined.
• One file may contain one or more classes (if a file contains no classes, it is considered a
script)
class Employee{
def Name = ""
def Age = 0
}
def emp = new Employee()
emp.Name = "Bill"
emp.Age = 25
println("Name - $emp.Name , Age - $emp.Age")
43. Class constructor
• With Constructor
class Employee{
def Name; def Age
Employee(name, age){
this.Name = name
this.Age = age
}
}
def emp = new Employee("Bill", 25)
println("Name - $emp.Name , Age - $emp.Age")
44. Class (cont’d)
• With Method
class Employee{
def Name; def Age
Employee(name, age){
this.Name = name
this.Age = age
}
def increaseAgeBy(byAge){
this.Age += byAge
}
def displayInfo(){
println("Name - ${this.Name} , Age - ${this.Age}")
}
}
def emp = new Employee("Bill", 25)
emp.increaseAgeBy(5)
emp.displayInfo()
45. Class (cont’d)
• Class can have Static methods, properties and fields
class Employee{
def Name; def Age
def static RetirementAge = 60
Employee(name, age){ }
}
println(Employee.RetirementAge)
class Employee{
private static _minJoiningAgeMale = 21
private static _minJoiningAgeFemale = 18
def static getMinJoiningAge(isMale = true) {
if (isMale){
return _minJoiningAgeMale
}
else{
return _minJoiningAgeFemale
}
}
}
println(Employee.getMinJoiningAge())
println(Employee.getMinJoiningAge(isMale = false))
46. Inner Class
• Inner classes are defined within another classes.
• The enclosing class can use the inner class as usual. On the other side, a inner class can
access members of its enclosing class, even if they are private.
• Classes other than the enclosing class are not allowed to access inner classes.
class Employee {
def name = ""; boolean isFTE = true
def GetSalary(){
def calc = new EmployeeSalaryCalculator()
calc.CalculateSalary()
}
class EmployeeSalaryCalculator{ // EmployeeSalaryCalculator is inner class
def CalculateSalary(){
if (isFTE) // can access field/properties of declaring class
100
else
75
}
}
}
def emp = new Employee()
emp.name = "Bill"
println(emp.GetSalary())
47. Inheritance
• Similar to Java inheritance, single inheritance tree - Inheritance from multiple
parent classes now allowed.
class Human {
def Talk(){
println "Human.Talk"
}
}
class Employee extends Human {
def Work(){
println "Employee.Work"
}
}
def e = new Employee()
e.Talk()
e.Work()
48. Inheritance (cont’d)
• Single inheritance tree - Inheritance from multiple parent classes now allowed.
class Living {
def name = ""
def walk() {
println "Living Walk"
}
}
class Human{
def think() {
println "Human Think"
}
}
class Employee extends Living, Human{ // Does not compile
def work() {
println "Employee Work"
}
}
def emp = new Employee()
emp.name = "AC"
emp.walk()
emp.think()
emp.work()
49. Abstract Class
• Abstract classes represent generic concepts, thus, they cannot be instantiated.
• Their members include fields/properties and abstract or concrete methods.
• Abstract methods do not have implementation, and must be implemented by concrete
subclasses.
• Abstract classes can have concrete methods, but should have atleast one abstract method
abstract class Living {
def name = ""
def walk()
println "Living Walk"
abstract def think()
}
class Human extends Living {
def think()
println "Human Think"
}
def human = new Human()
human.name = "AC"
human.walk() // Living Walk
human.think() // Human Think
50. Interface
• Defines a contract that a class needs to conform to - only defines a list of methods
that need to be implemented, but does not define the methods implementation.
interface Walkable{
def walk()
}
interface Runnable{
def run()
}
class Human implements Walkable,Runnable{
def walk(){
println "I can walk"
}
def run(){
println "I can run"
}
}
def human = new Human()
human.walk() // print “I can walk”
human.run() // print “I can run”
51. enum
enum Employees {
FTE, Contractor
}
def emp = Employees.FTE
switch (emp) {
case Employees.FTE:
println "You are a FTE"
break
case Employees.Contractor:
println "You are a Contractor"
break
}
52. Exception handling
• Same as Java – supports try, catch, finally. Supports multi catch similar to Java
def main(){
def errorType = 1
try {
switch(errorType) {
case 0:
throw new ArithmeticException("Can not divide by zero")
break
case 1:
throw new IOException("IO exception ocurred")
break
case 2:
throw new Exception("Looks like something went wrong")
break
}
}
catch(ArithmeticException | IOException ex) {
println ex
}
catch(Exception ex) {
println ex
}
finally {
println "finallly block called"
}
}
main()
53. GDK – Groovy Development Kit
• Similar to JDK, Groovy has a GDK (Groovy Development Kit) that has extra
functionality (additional API) on top of Java JDK.
• Example – Additional functionality for string and number type, File handling, I/O,
additional Date & Calendar classes etc.
def str = "Groovy"
println str
println(str.count("o"))
println(str.contains("g"))
println(str.center(20))
println(str.multiply(4))
println(str.reverse())
println(str.minus("vy"))
str = "notepad"
str.execute()
55. Closure
• In Groovy, Closure is anonymous block of code that can take arguments, return a
value and be assigned to a variable
• Closures could be passed as parameter to functions and could be returned from
functions
• A closure may reference variables declared in its surrounding scope.
• Closure syntax -
{ [closureParameters -> ] statements }
def var_name = { [closureParameters -> ] statements }
56. Closure
• Without a parameter
def work = { println "Work Called" }
work()
• With a parameter
def sayHello = { name -> println("Hello $name") }
sayHello("Shreya")
def add = { a,b -> a+b }
// this is same as declaring a regular method/function
// def add2(a,b) { return a+b }
println(add(20,10))
57. Closure Parameters
• Parameters of closures follow same principle as parameters of regular methods:
• an optional type
• a name
• an optional default value
• parameters are separated by comma
def add = { a, b=100 -> a+b } // b has a default value of 100
println(add(20))
def sub = { a=20, b=10 -> a-b } // both a & b has default values
println(add(b:120, a:90))
def sub = { a=20, b=10 -> a-b } // both a & b has default values
println(sub(b=120, a=90))
• With a parameter
58. Currying
• In Groovy, currying refers to the concept of partial application.
• Currying in Groovy will let you set the value of one parameter of a closure, and it
will return a new closure accepting one less argument.
• It does not correspond to the real concept of currying in functional programming
because of the different scoping rules that Groovy applies on closures.
Left Currying: Sets the left most parameter of a closure
def displayMsg = {noOfTimes, message -> println(message * noOfTimes) }
displayMsg(5, "Hello") // prints HelloHelloHelloHelloHello
// First Level of Currying – sets the first most parameter of the
// closure noOfTimes to 2
def displayMessageTwice = displayMsg.curry(2)
displayMessageTwice("Groovy") // prints GroovyGroovy
// Second Level of Currying
def displayHelloTwice = displayMessageTwice.curry("Hello")
displayHelloTwice() // prints HelloHello
59. Currying
Right Currying: Sets the right most parameter of a closure
def displayMsg = {noOfTimes, message -> println(message * noOfTimes) }
displayMsg(5, "Hello") // prints HelloHelloHelloHelloHello
// First Level of Currying – sets the right most parameter of the
// closure message to Groovy
def displayGroovy = displayMsg.rcurry("Groovy")
displayGroovy(3) // prints GroovyGroovyGroovy
// Second Level of Currying
def displayGroovyFourTimes = displayGroovy.rcurry(4)
displayGroovyFourTimes() // prints GroovyGroovyGroovyGroovy
60. Trait (aka Mixins)
• Single line comment
GrandParent
Parent
Child
Single Inheritance
Parent1
Child
Parent2
Multiple Inheritance using
Inheritance hierarchy
GrandParent1 GrandParent2 Vehicle
Car HasAC
Mixin
Base class
Inheritance hierarchy
61. Trait
• Single line comment
trait Flyable{
def fly(){
println "I can fly"
}
}
trait Runnable{
def run(){
println "I can run"
}
}
class Bird implements Flyable, Runnable{
}
def bird = new Bird()
bird.run() // prints "I can run"
bird.fly() // prints "I can fly"
62. Groovy style guide
• Do not use semicolon for terminating statement / end of line
• Not using return statement
• Do not use both def and type while declaring variables (def String city = “Blore”) –
use either def or type
• For scripting def is more suitable for most cases
• Do not use explicitly public for classes and methods as Groovy makes them public
by default
• Use Groovy properties instead of private backing field and java style getter, setter
• User string interpolation instead of manually formatting the string
• Try to use Groovy Collection classes (range, list, map) before Java collection
classes
http://www.groovy-lang.org/style-guide.html