Java vs Groovy Vs Kotlin for Scripting

API Expert
5 min readJun 19, 2023

People have OFTEN (and I mean REALLY OFTEN) complained about the verbosity of Java versus scripting languages like Python which allow you to code far more quickly.

Well recently, in the JDK 21, Java is trying to make a COUPLE changes to fix this but not enough to really make a difference. Thats why languages like Groovy and Kotlin exist on the JDK… to be able to provide a choice for people who prefer scripting and CLI.

So today I thought I would show a concise comparison of the three for scripting and CLI to show the features and what they can do

Compiling : [Groovy]

ex of Gradle compiling Groovy/Java sources in project using Groovy compiler

Shell Scripting : [Groovy]

  • Java: Java was never intended for shell scripting and requires addon’s to accomplish this. The best current addon to accomplish this is JBang which is an addon for ALL JDK langs.
  • Kotlin: Kotlin has this but it is an addon called ‘kscript’ which does not have all the functionality of the Kotlin library.
#!/usr/bin/env kotlinc -script
  • Groovy(*): Groovy supports this natively with a ‘shebang’ and has all the functionality of Java libraries and Groovy libraries at your fingertips. You can even import additional libraries not on your system using ‘Grapes’.
#!/usr/bin/groovy

Static/Dynamic Typing : [Groovy]

  • Java : Java is only static typed (thus why people say it is overly verbose)
  • Kotlin(*): Kotlin doesn’t feature implicit conversions between which makes it strongly statically typed.
  • Groovy(*): Groovy can be static/dynamic typed; the conversion is handled by the compiler at runtime (thus allowing for JIT). This makes it easier to learn and faster to develop in as once a project is ‘stable’, conversion can be enforced with the ‘compilestatic’ annotation thus converting dynamic type to static type on the final phase prior to release; this saves tremendous amounts of time on testing and development.
// both the following will compile in Groovy

// map done dynamically
def map1 = ['flinstones':{'fred','wilma','dino','pebbles']]
// map done statically
LinkedHashMap<String,ArrayList> map2 = ['flinstones':{'fred','wilma','dino','pebbles']]

CLI Script : [Groovy]

  • Java: Here is where the verbosity in Java shows itself. Creating a CLI in Java requires alot of overhead as seen from this example. It is not quick or simple (see shell scripting)
  • Kotlin: Kotlin is a ‘little better’ but is still requiring gradle and a full application build.
  • Groovy: With Groovy it is still a script (not a giant project). You do not need an entire project or jar to create a script… just a simple script (hence why it is called scripting).

Collection Initialization

  • Java: Java has no collection initialization and requires you to ADD each element one at a time!
Map<String, String> doubleBraceMap  = new HashMap<String, String>() {{
put("key1", "value1");
put("key2", "value2");
put("key3", "value3");
put("key4", "value4");
}};
  • Kotlin: Kotlin is better in that it allows collection initialization but still is verbose about it.
val states = mapOf("AZ" to "Arizona", "WA" to "Washington", "IA" to "Iowa")
  • Groovy: With Groovy, collection initialization is similar to Python, Ruby and other existing languages where this is a standard.
def states = ['AZ':'Arizona','WA':'Washington','IA':Iowa'

Python/Ruby Example

states = { "AZ":"Arizona", "WA":"Washington", "IA":"Iowa"}

Switch Statement Comparison Operators

  • Java: Java has very limited switch statement operators in which you can only do basic comparator functions
  • Kotlin: Kotlin does NOT HAVE SWITCHES. Instead it has ‘when’ statements. These act as switches and can have alot of functionality but are not similar to industry standard ‘switch statements in EVERY LANGUAGE.
when(x){
"something" -> {
println("something")
}
else -> {
println("something else")
}
}

when(y){
1 -> println("one")
2 -> println("two")
}

when {
x.equals("something", true) -> println("something")
x.equals("else", true) -> println("something else")
}
  • Groovy: Groovy uses the industry standard ‘switch’ statement but expands it so that you can use a variety of comparator operators with it: regex matching, class matching, ranges, map contains, list contains, etc.
def testSwitch(val) {
switch (val) {
// number match
case 52 -> 'Number value match'
break;
//string match
case "Groovy 4" -> 'String value match'
break;
// regex match
case ~/^Switch.*Groovy$/ -> 'Pattern match'
break;
// class match
case BigInteger -> 'Class isInstance'
break;
// range contains
case 60..90 -> 'Range contains'
break
// list contains
case [21, 'test', 9.12] -> 'List contains'
break;
// object equals
case 42.056 -> 'Object equals'
break;
// closure
case { it instanceof Integer && it < 50 } -> 'Closure boolean'
break;
// map contains
case [groovy: 'Rocks!', version: '1.7.6'] -> "Map contains key '$val'"
break;
default -> 'Default'
}
}

Speed

  • Java: Java is obviously the fastest of them all but…
  • Kotlin: In some ways Kotlin CAN be faster than Java…
  • Groovy: And in other ways Java can be faster than both. Recently, Gradle switched from Groovy to Kotlin as their base language and they had a HELL of a time because developers kept complaining about the build time being slower. They tested over and over and found that Groovy’s compiler was just faster than Kotlin and thats all there was to it…

Conclusion

Every language has it’s purpose and it’s pluses, and in this case, the Apache Groovy language is overwhelmingly better at scripting/cli on the JDK than the other JVM languages.

I would highly suggest anyone looking to learn Java to first check out Groovy as it is a great first step into the world of Java and the JVM.

Additional Links

--

--

API Expert

Owen Rubel is the 'API Expert'. He is an Original Amazon team member, Creator of API Chaining(R), Leader in API Automation