'Groovy's True Object-Orientation' post illustration

Groovy's True Object-Orientation

avatar

Unlike Java, which mixes primitive and reference types, Groovy handles everything in common manner — as objects, what makes it truly object-oriented. When a primitive type gets passed into the Groovy world, it is automatically “boxed” into its object equivalent, and vice versa. This allows Groovy to support some interesting concepts like methods on primitives, operator overloading and The Groovy Truth. Let’s look at them more closely.

Methods on primitives:

In Groovy it is absolutely eligible to make method calls on primitives, just like this one: 5.minus(7). As you know, Groovy source code is compiled into Java bytecode, which in turn runs on JVM where such things are not possible. So, how does Groovy carry out this trickery? Let’s find out! Try this:

1
2
3
int number = 3
println number
println number.getClass()

After running it you will see in the output:
3
class java.lang.Integer

It is clearly visible that Groovy has converted primitive int into Integer class. So, in fact all primitives in Groovy are just visionary and are automatically boxed into corresponding wrapper classes, exposing due methods for our use. Along with Groovy’s way of passing closures as method arguments we can do pretty slick things. Here’s an example:

1
2
3
3.times {
   print it
}

This code uses void times(Closure closure) method of Number class, which is a superclass of Integer, and will give “012” as an output. Or another one: void upto(Number to, Closure closure):

1
2
3
7.upto(9.99) {
    print it
}

Will print “789”

Operator overloading:

As I mentioned, Groovy is a true object-oriented language, and this extends to the operators themselves. In Groovy it is possible to do things like this:

1
2
3
def list = []
list << 'car' << 'bike'
println list

Which will print [car, bike]

In Java “<<” means bitwise left shift and nothing else. What Groovy does is translates all operators into method calls, that’s right, “<<” becomes “.append()”. This means that you can change default behavior of any operator. We can put a little experiment to test this:

1
2
3
4
5
6
7
8
class A {
    def plus(addend) {
        println "I am adding $addend"
    }
}

def a = new A()
a + 2

Will print “I am adding 2”

All operators follow naming convention, here are few of them:
a == b a.equals(b)
a * b a.multiply(b)
a / b a.divide(b)
a++ a.next()
a-- a.previous()
a <=> b a.compareTo(b)
You can find comprehensive list here.
The good news is that all such operators handle nulls gracefully avoiding the throwing of java.lang.NullPointerException. So, you don’t have to worry if ‘a’ is a null before making a comparison.

The Groovy Truth:

In Groovy booleans aren't the sole things that can be evaluated to true or false, but for instance, null references, number zero, empty strings or collections are evaluated to false. This makes code to be infinitely cleaner, especially in the context of web applications given the amount of string evaluation necessary.

Again, this is possible due to implicit method invocation and, as always, you can customize it for your needs in your own classes. Let’s make sure:

1
2
3
4
5
6
7
8
9
10
11
class A {
    boolean asBoolean() {
        println 'Сonverting to boolean'
        return true
    }
}

def a = new A()
if (a) {
    println "It's true!"
}

And here’s the output:
Converting to boolean
It's true!

If you're looking for a developer or considering starting a new project,
we are always ready to help!