Skip to the content.

Groovy Traits static and instance init blocks

2018-11-17

This is our first post!

Today we will show an example of a new useful Groovy Traits feature:

Note: it seems that this is first post about this feature as it was implemented just a few days back thanks to Groovy Team and paulk_asert.

Let’s consider below use case:

This is a classical example when multiple inheritance can be applied.

Moreover - this is the case when static and instance init blocks can be used.

Java does not support multiple inheritance except for the interfaces.

That is where Groovy comes to our help - with the awesome “traits” concept.

And starting from Groovy version 2.5.5 - the “traits” can support init blocks - allowing multiple inheritance of initialization traits.

Note: If class implements more than 1 trait containing static init block - all the static init blocks are invoked. To illustrate this we added “InitLoggingTrait”.

Let’s try it out!

trait InitLoggingTrait {
    static {
        printlnFormatted "Init Class"
    }
    static void printlnFormatted(String string) {
        System.out.println(String.format("%s : %s : %s", Thread.currentThread().getName().padRight(30), getMetaClass().getTheClass().getSimpleName().padRight(30), string))
    }
}
trait InstanceCounterTrait {
    static private Integer instanceCounter //immutable, non-shareable
    static {
        instanceCounter = 0
    }
    {
        instanceCounter = instanceCounter + 1
        setName(getClass().getSimpleName() + instanceCounter)
    }
}
class SenderThread extends Thread implements InstanceCounterTrait, InitLoggingTrait {
    void run() {
        printlnFormatted "Run (Sending)"
    }
}
class ReceiverThread extends Thread implements InstanceCounterTrait, InitLoggingTrait {
    void run() {
        printlnFormatted "Run (Receiving)"
    }
}
Thread.currentThread().setName("Main")
System.out.println("Thread Name".padRight(30) + " : " + "Class Name".padRight(30) + " : Message")
System.out.println("---------------------------------------------------------------------------")
(0..3).each {
    new SenderThread().start()
    Thread.sleep(200)
    new ReceiverThread().start()
    Thread.sleep(200)
}

And the result:

Thread Name                    : Class Name                     : Message
---------------------------------------------------------------------------
Main                           : SenderThread                   : Init Class
SenderThread1                  : SenderThread                   : Run (Sending)
Main                           : ReceiverThread                 : Init Class
ReceiverThread1                : ReceiverThread                 : Run (Receiving)
SenderThread2                  : SenderThread                   : Run (Sending)
ReceiverThread2                : ReceiverThread                 : Run (Receiving)
SenderThread3                  : SenderThread                   : Run (Sending)
ReceiverThread3                : ReceiverThread                 : Run (Receiving)
SenderThread4                  : SenderThread                   : Run (Sending)
ReceiverThread4                : ReceiverThread                 : Run (Receiving)

Happy hacking!

Live Groovy. Code Groovy.