1) Introduction
Groovy is an Object Oriented Scripting Language which provides Dynamic, Easy-to-use and Integration capabilities to the Java Virutual Machine. It absorbs most of the syntax from Java and it is much powerful in terms of funtionalities which is manifiested in the form Closures, Dynamic Typing, Builders etc. Groovy also provides simplified API for accessing Databases and XML. Groovy language is large in terms of functionalities and concepts and this article provides only the basic Introduction and Information about Groovy. The first section of the article concentrates on the very basic concepts and theories of Groovy like Declaring Variables, Flow Control and Looping Structures. Then the next section focusses on Declaring Classes, Objects, Methods and the different ways of accessing them in Groovy. Covered in depth are the most exiting Groovy Closures. Finally the article explored the Groovy Distribution along with the various available Utilities.
also read:
2) Basics of Groovy
2.1) The Traditional Hello World Program
Learning a new language generally involves a lot of time and energy because the various program elements like Syntax, Operators, Declarations, Control Structures etc. have to be remembered. But, learning Groovy don’t consume much time as the Language Syntax resembles the same as Java. Before going into the various pieces of Program Elements, let us see a simple and the traditional Hello World Program in Groovy.
Copy and Paste the following code in your favorite text Editor. Before running the script, make sure that you have downloaded the Groovy Distribution available at http://dist.groovy.codehaus.org/distributions/groovy-binary-1.1-BETA-1.zip. Following is the code listing for printing the traditional Hello World Program in Groovy.
Hello.groovy
// Printing the word "Hello" using Groovy. print "Hello\n"
Note that it is not necessary that the Groovy Files must have an extension '.groovy'
. It can be anything. Go the command prompt and set the path variable pointing to GROOVY_HOME\bin
. Suppose if Groovy is installed in the directory C:\Groovy-1.1
, then the path variable must be pointing to C:\Groovy-1.1\bin;
.
Setting the Path Variable
set path=%path%;GROOVY_HOME\bin;
After that give the following command and you will see the text “Hello” followed by a new line in the output.
Running the Groovy Program
groovy Hello.groovy
2.2) Declaring Variables
In the previous section, we saw how to write a simple Hello World program using Groovy. Now let us dig into the various Language Basics of Groovy. More specifically, the subsequent sections will tell you how to Declare variables, Defining Control Structures and the various Looping Constructs etc. Variables or Objects have to be declared before being referenced somewhere. The simple way to declare a variable is to just a name along with some value. For example, the following code declares a variable name called 'name'
with the value 'Johny'
.
// Defining a variable called 'name' in Groovy and assigning it with a value. def name = "Johny"
The keyword ‘def’ stands for definition. It is also possible to ignore the keyword 'def'
during variable declaration. So, the following code is also possible.
name = "Johny"
If we want to take the value of a variable then the '$'
sign should be prefixed along with the variable name. For example, the following code will print "Hello Johny"
in the console.
def name = "Johny" print "Hello $name \n"
By default, the Java Packages java.lang.*
, java.util.*
, java.io.*
, java.math.*
, java.net.*
will be included automatically by the Groovy Intepreter. The declaration of a Java Object within Groovy follows the same standard as that of a normal Variable. For example the following example shows the usage of the import statement as well as referencing Java Objects within the Groovy Environment,
Declarations.groovy
def strObject = new String("Groovy") print strObject.length() // Import statement can occur anywhere import java.sql.* Connection connection import java.lang.reflect.Method Method aMethod
Having done with the basics of Declaring variables and Objects in Groovy, let us now see how to declare Collection Data Types in Groovy. The syntax of declaring a Collection object in Groovy is very simple and the following code snippet will prove that,
Collection.groovy
// Define a Collection called numbers holding 1, 2 and 3 def numbers = [10, 2, 33] // Iterate over the collection and print it. for (number in numbers){ println number } // Add two more entries to the Collection. numbers.add(14) numbers.add(57) // Iterate again over the Collection to see the new values. for (number in numbers){ println number }
The above code declares a collection populated with elements using the [] syntax. All elements within [] forms the elements in the collection. Elements in the collection are traversed using the Enhanced For Loop (also called for-each). Elements are also added dynamically to the Collection using the add() method.
Here is the output for the above program.
Output
10 2 33 10 2 33 14 57
2.3) Working with Control Structures
Let us look into the various Control structures like If-Else, For Loops and While Loops in this section. The syntax for the Conditional Statements resembles very similar to the one that we normally see in programming languages like C, C++ or Java. Following is the syntax for If-Else Construct.
if ( booleanExpression ){ // Set of Statements }else{ // Other Set of Statements. }
The thing to note in the above syntax is which and all evaluates to a boolean expression is Groovy. Consider the following set of statements,
Construct.groovy
boolValue = true notEmptyStr = new String("Hello"); numberList = ["1","2", "3"] if (boolValue && notEmptyStr && numberList) { println "Condition is true" }else{ println "Condition is false" } boolValue = false emptyStr = new String(""); emptyList = [] if( boolValue || emptyStr || emptyList){ println "Condition is true" }else{ println "Condition is false" }
Here is the output for the above program.
Output
Condition is true Condition is false
Consider how Groovy evaluates the String Object and the Collection Object when being used in the Conditional Construct. A String or a Collection object will return true if the Object is not null or empty.
2.4) Looping Constructs
This section looks into the syntax and the structure of 'for'
and 'while'
loop constructs in Groovy. The syntax looks very similar to Java and it also provides much more powerful functionality than Java Constructs as the following code snippets will prove.
The syntax of the for loop is given below,
for(Object in IterableObject){ // Set of Statements. }
The above looks very similar to the Enhanced For Loop (starting from 5.0) in Java. Let us now see what it is an Iterable Object. An Iterable Object is usually a Composite Object having multiple Child Entries that can be iterated over. In Java terms, this exactly means any Object that implements the java.lang.Iterable interface
. Most of the Collection Objects like List
, Set
, etc. all implements the Iterator interface which provides a method called Iterable.iterator()
, using that elements with the Composite Object can be iterated over.
Consider the following code snippets for Iterable Object in Groovy.
Loop.groovy
// A String is nothing but a sequence of characters. def hello = "Hello" for(aChar in hello){ println aChar } // A Collection object holding the four seasons. def seasons = ["Winter", "Season", "Spring", "Autumn"] for(season in seasons){ println season } // Even a File Object can be iterated in Groovy. String thisFileName = "Loop.groovy" thisFile = new File(thisFileName) for(aLine in thisFile){ println aLine }
The output for the above program will look something like the following.
Ouput
H e l l o Winter Season Spring Autumn def hello = "Hello" for(h in hello){ println h } def seasons = ["Winter", "Season", "Spring", "Autumn"] for(season in seasons){ println season } // Even a File Object can be iterated in Groovy. String thisFileName = "Loop.groovy" thisFile = new File(thisFileName) for(aLine in thisFile){ println aLine }
Since a String Object represents a Collection of Characters, it can be considered as an Iterable Object, so is the case of a Collection Object. Examine how the File object is traversed over to print the whole contents. Since a File logically represents a collection of lines followed by new line characters, in Groovy terms, a File object can also be imagined as an Iterable Object.
Following is the syntax of the while loop which resembles very similar to the traditional programming languages like C or Java.
while (condition){ // Repeat the loop till the condition remains true. }
3) Classes, Methods and Objects Declaration in Groovy
In this section, we will cover the how Classes and Objects into the groovy Environment. More specifically, we will see how to declare Groovy classes, define class methods, creating Objects etc. Creation of classes in Groovy almost follows the same syntax and semantics of the Java Language. However, there are quite a number of interesting and easy to use features available in Groovy. For example, consider the following class declaration called Product
.
Product.groovy
class Product{ private String name private def price def vendor public Product(){ } Product(name, price, String vendor){ this.name = name this.price = price this.vendor = vendor } public String getName(){ return name } def setName(name){ this.name = name } public String getPrice(){ return price } def setPrice(price = 100.00){ this.price = price } def toString(){ return "Name = $name, Price = $price, Vendor = $vendor"; } static main(arguments){ def p1 = new Product("Mobile", "10000", "Nokia") println(p1.toString()) def p2 = new Product(name: 'Laptop', price: "540000", vendor: "IBM") println(p2.toString()) def p3 = new Product() p3['name'] = "Television" p3.'price' = "45454" p3['vendor'] = "Samsung" println(p3.toString()) def p4 = new Product(name: "DVD Player", vendor: "TCL") p4.setPrice(); println(p4.toString()) } }
The following is the output for the above program.
Ouput
Name = Mobile, Price = 10000, Vendor = Nokia Name = Laptop, Price = 540000, Vendor = IBM Name = Television, Price = 45454, Vendor = Samsung Name = DVD Player, Price = 100.00, Vendor = TCL
Lots and lots of interesting things are there in the above code. Since Groovy is a Scripting language it is a Loosely Typed Language. What is meant by a loosely typed language is that, there is no need to define the data-types for the variables and for the return type of the methods. The defaults (which are very specific to the particular Scripting Languages) will be taken. Same is the case of Groovy.
For example, in the declaration section, we didn’t mention the data-type as well the modifier of the variables. Groovy’s default access modifier is public. Also examine the same standards followed in one of the method definition. Groovy also supports Default Parameters, which means that, if you didn’t pass any value to a particular parameter in some method definition, then the default value will be taken.
For example consider the method signature,
def setPrice(price = 100.00){ this.price = price }
The above method setPrice()
has one parameter and that too a default parameter having a value of 100.00
. If the callee doesn’t pass any argument to this method, then the value of 100.00
, which is the default, will be taken for the price
field.
Groovy support various ways of supply values to an object of a class. One is the traditional Constructor, Named Parameter Support and the Property-based Access. Let us see these approaches one by one.
The first way is to define a Constructor for a class and to supply values for the object directly during the time of Instantiation. For example, our sample class Product
has a three argument constructor defined like this,
Product(name, price, String vendor){ this.name = name this.price = price this.vendor = vendor }
and the instantiation of the product p1
uses this Constructor to give the initial values to the object.
def p1 = new Product("Mobile", "10000", "Nokia")
The second object p2
uses the named parameter support to give values to the object. Watch carefully the syntax for this, the field name followed by a colon and then the value for the field.
def p2 = new Product(name: 'Laptop', price: "540000", vendor: "IBM")
The third object p3
is making using the property-based support for instantiating the object. The general syntax for accessing a property for a class is ObjectName.'propertyName'
or ObjectName.['propertyName']
and the same rule has been followed while
instantiating the object p3
.
4) Groovy Closures
Closures aren’t new concepts in programming languages. In fact they have been there in the world a long back. C supported Closures in the form of Function Pointers and C# in the form of Delegates. Let us look into what Closures are. Closures in Groovy represent some set of statements, very similar to functions that contain a piece of functionality. The most important difference between a normal functional and a Closure is that Closures can passed onto other functions as arguments and they serve as Callbacks to the calling function. Couple of examples in the subsequent sections will make the concept clearer.
Let us look into the syntax definition of a Closure,
def refToClosure = { ParameterList -> Set of Statements }
Note the syntax definition of a Closure. A Closure is usually defined within the braces {… }
. ParameterList defines the list of parameters that are to be passed for the closure. The symbol '->'
is used to separate the Arguments List with the set of statements in the Closure Definition.
Simply defining a closure doesn’t serve any purpose until they are called and their functionality used by someone. Following is the syntax to call a Closure Definition.
refToClosure.call( argumentList )
Even the following can be used,
refToClosure( arguments )
Let us look into some sample closures in the subsequent sections. The following defines a closure which takes no arguments.
def printClosure = { println "Hello" } printClosure() printClosure.call()
Since there is no '->'
and possibly there are no parameters defined before that, we can clearly tell that the above Closure doesn’t take any arguments. Consider the following closure example that takes two parameters.
def argPrintClosure = { String name, int age -> println "Printing $name and $age" } argPrintClosure("Jennie", 10) argPrintClosure.call("Andrew", 20)
The above closure which is pointed by argPrintClosure
takes two parameters namely 'name'
and 'age'
. Note how the arguments are passed to the Closure Definition while calling it.
Like 'this'
keyword which refers to the current object, there is 'it'
keyword which, when used within a Closure Definition refers to the default first parameter being passed to the method. The following code will prove that,
def implicitArgClosure = { println it } implicitArgClosure.call("hello") implicitArgClosure.call()
Within the closure definition, we have referenced the 'it'
keyword, which points out the first default parameter in the closure definition (even though we don’t have defined it). When the Closure Definition is invoked with the value "hello"
, 'it'
is substituted with "hello"
and the following gets printed. If no value is passed onto the closure definition, then null gets printed.
Logically speaking since a closure is equivalent to some set of statements in a function definition, even a closure can be made to point directly to a functional definition. Following code will illustrate this,
class ClosureTest{ public void printClosure(String value){ println value } } def obj = new ClosureTest() Closure closureObj = obj.&printClosure closureObj.call("Test")
In the above code, we want the printClosure function to resemble as a Closure. For that we obtain a reference to the closureObject with the following syntax, objectName.&methodName
. Note that this will return a reference to the method in the form of a Closure object. Then, as usual, the closure can be invoked (which means that the function is invoked) by using the 'call()'
statement.
The most important point in using Closures is that they can be passed as arguments to other method definition thereby acting as Callbacks. Most of the methods in the Groovy Collection API accept a Closure as their argument. In such cases, repeated logics that have to be performed on the elements of the Collection can be encapsulated in the form of Closures. For example, consider the following piece of code,
def oddClosure = {element -> Number number = Integer.parseInt(element) if (number%2 != 0){ print number + " " } } def evenClosure = {element -> Number number = Integer.parseInt(element) if (number%2 == 0){ print number + " " } } def numbers = ["1", "2", "3", "4", "5", "6", "7", "8"] print ("Odd Numbers-->") numbers.each(oddClosure) println "" print ("Even Numbers-->") numbers.each(evenClosure) println ""
In the above code, two closures have been defined namely 'oddClosure'
and 'evenClosure'
and they have a simple piece of logic to find and print whether a number is odd/even respectively. And in the subsequent code, a collection of numbers is defined with the 'each'
method called by passing the respective Closures. Now the set of statements within the Closure will act as Callbacks as for every element in the Collection, the processing will be handed over to the closure which executes the appropriate logic.
5) Groovy Distribution
5.1) Introduction
This section covers the various Utilities that come along with the Groovy Distribution. Following are the utilities that are covered brief in the subsequent sections.
- Groovy Intepreter
- Groovy Compiler
- Groovy Shell
- Groovy Console
Let us see them one by one.
5.2) Groovy Intepreter
An Intepreter is something which executes the Source Code on the fly without generating Intermediate Files. Till now, we are running the Groovy programs with the help of Groovy Intepreter only. In Groovy distribution, the Intepreter is available in the form of groovy.bat
. To execute a Groovy Program, simply type groovy followed by the path of the Groovy file. For example, the following command executes the Hello.Groovy file available in the src
directory.
groovy src/Hello.Groovy
One thing to note about Groovy Intepreter is that, whenever a Groovy File is fed, the Groovy Parser will parse checking for any Syntax or Construct mismatch. Then the conversion of the Groovy Source File into Java Byte-code will take place, followed by the invocation of the JVM on the byte-code.
5.3) Groovy Compiler
Invoking the Groovy Intepreter against a Groovy File may be time consuming especially if the size of the Groovy File is large. In such cases, optimization of the execution of the Groovy Script Files should be taken into consideration. Execution of the script files can be optimized by using a Groovy Compiler. The two step process of executing a Groovy File using Groovy Compiler is mentioned as below,
- Conversion of the Groovy File into a .class File using the Groovy Compiler
- Running the Class File using the Java Intepreter
Suppose that we have a file called Hello.groovy
then the following command can be used to convert the groovy file into a class file.
groovyc Hello.groovy –d classes
In the above command, groovyc is the name of the Groovy compiler operating on the File Hello.groovy
. The option '-d'
represents the directory for the Generated Java Class files.
Running the Generated Class File using the JVM mandates the classpath to point to groovy-all-1.1-BETA-1.jar
which is located in the GROOVY_HOME\embeddable
location. This Jar file contains groovy specified libraries which must be added to the classpath before running the Hello.class
file.
set classpath=%classpath%;GROOVY_HOME\embeddable\groovy-all-1.1-BETA-1.jar; java classes\Hello.class
5.4) Groovy Shell
The Groovy Shell provides the Command Line Environment for running Groovy Scripts. To start the Groovy shell, simply type groovysh
(Groovy Shell) in the command prompt.
groovysh
After entering into the Groovy shell, statements can be entered and executed directly. For example, suppose we wish to add two numbers and tell print the result value, then the following command along with statements will help.
groovy> def number1 = 10 groovy> def number2 = 32 groovy> def number3 = number1 + number2 groovy> println "Addition of $number1 plus $number2 is $number3" groovy> go Addition of 10 plus 32 is 42
The 'go'
command is used to execute the command containing the statements that were previously entered.
5.5) Groovy Console
The Groovy Console provides a Graphical User Interface for typing and executing Groovy Scripts. To invoke the Groovy console, type groovyConsole in the command prompt that will open the following window.
Command Statements can be typed into the upper text-field and can be executed by pressing the Ctrl+R
key or Actions->Run
Menu. Scripts can be saved by using Ctrl+S and the existing Script can be loaded and executed by using the combination of Ctrl+O
and Ctrl+R
.
6) Conclusion
Groovy language is big and this article focused on covering only the basic Language Construts that are available in Groovy. Groovy also has an extended Library API called the GDK, Groovy Development Kit, which extends the Java Development Kit. This article which started off with the Basic Language constructs like Syntax Declaration, If-Else constructs, Looping Constructs provides plenty of Samples that are appropriate for the discussion. They it went on with the concetps of Declaring and Defining Classes and Objects in Groovy. Plenty of theories and Samples were presented in the section on Closures. Finally it ended up with a brief discussion on the various Utilities that are available along with the Groovy Distribution.
The following are some of the popular articles published in Javabeat. Also you can refer the list of groovy articles and groovy books from our website. Please read the articles and post your feedback about the quality of the content.
- Creating JSON using Groovy
- Introduction to Groovy Server Pages (GSP)
- Web Development in Groovy using Groovlets
If you are interested in receiving the future java articles from us, please subscribe here.