Syntax Basics and Differences from Java

3.1 Optional Elements

Semicolons are optional. Parentheses can be omitted for method calls with at least one argument (not for zero-argument calls).

Default imports: java.lang.*, java.util.*, java.io.*, java.net.*, groovy.lang.*, groovy.util.*, java.math.BigInteger, java.math.BigDecimal.

Public by default: classes and methods are public. Fields without modifiers become properties (private field + getter/setter).

println("with parens");          // Java-like
println "without parens"         // optional parentheses for top-level calls with arguments
def add(a, b) { a + b }          // `return` optional: the last expression is returned

3.2 Comments

// single line
/* multi-line */
/** Groovydoc comment */
#!/usr/bin/env groovy     // shebang line (first line of a script)

3.3 Key Differences from Java

Calls equals() (or compareTo() for Comparables). Use is() or === for identity.

Must declare or catch Overload chosen at compile time Overload chosen at runtime by argument types (dynamic mode) int[] a = {1, 2}

int[] a = [1, 2] ({} is a closure). Java syntax is supported since Groovy 3.

public (use @PackageScope for package-private) '...', "..." (GString), '''...''', """...""", /.../, $/.../$ char literals

'a' is a String. Use 'a' as char or (char) 'a'.

Everything behaves like an object (primitives are optimized when possible)

Closures { x -> x * 2 }. Java lambda syntax is supported since Groovy 3.

Groovy Truth: empty, null, and 0 are false

3.4 Identifiers and Keywords

Java-like identifiers, plus Groovy keywords: as, def, in, trait, var (Groovy 3+), record, sealed, permits, non-sealed, yields.

Quoted identifiers are allowed after a dot: map."with space", obj.'my-prop'.