The enhanced Groovy switch statement goes far beyond Java’s version. See 10 examples matching strings, ranges, regex, classes, and closures. Tested on Groovy 5.x.
“Java’s switch is a gate with a few locks. Groovy’s switch is a gate that accepts fingerprints, retina scans, and a secret handshake.”
Martin Fowler, Refactoring
Last Updated: March 2026 | Tested on: Groovy 5.x, Java 17+ | Difficulty: Beginner to Intermediate | Reading Time: 20 minutes
The groovy switch statement goes far beyond what Java offers. Where Java limits you to matching integers, enums, and strings with mandatory break statements, Groovy’s version matches ranges, regular expressions, class types, collections, closures, and even custom objects – with no fall-through by default.
Groovy’s switch statement throws all those limitations out the window. It can match against strings, ranges, regular expressions, class types, collections, closures, and even custom objects. And there’s no fall-through by default, so you don’t need break – though you can still use it if you want.
In this post, we’ll walk through 10 practical groovy switch examples that demonstrate why it’s one of the most flexible control flow tools in the language. If you’re coming from our posts on Groovy for loops or the times() loop, you’ll see how switch fits naturally alongside those constructs for building clean, expressive logic.
Table of Contents
What Makes Groovy Switch Special?
The secret behind Groovy’s switch is the isCase() method. When you write a case expression, Groovy doesn’t just check for equality. Instead, it calls caseValue.isCase(switchValue) behind the scenes. Different types implement isCase() differently:
| Case Type | isCase() Behavior | Example |
|---|---|---|
| Object (default) | Calls equals() | case 'hello': |
| Class | Calls isInstance() | case String: |
| Range | Calls contains() | case 1..10: |
| Collection/List | Calls contains() | case [1, 3, 5]: |
| Pattern (regex) | Calls matcher().matches() | case ~/\d+/: |
| Closure | Calls the closure | case { it > 10 }: |
According to the official Groovy semantics documentation, this design makes Groovy’s switch “much more powerful than the one in C or Java.” You can even define isCase() on your own classes to make them work as case values. That’s a level of extensibility you won’t find in most languages.
Key differences from Java’s switch:
- No fall-through by default – each case branch exits automatically
- The
breakkeyword is optional (only needed if you want to break from a specific point) - Case values can be any type – not just constants
- Multiple case types can be mixed in the same switch
- Switch can be used as an expression that returns a value
Syntax and Basic Usage
The basic syntax looks just like Java – but under the hood, it’s far more flexible. Here’s the general structure:
Groovy Switch Syntax
switch (variable) {
case value1:
// code for value1
break // optional in Groovy
case value2:
// code for value2
break
default:
// code if no case matches
}
Let’s start with the simplest use case and progressively explore more advanced features. If you’re still getting comfortable with Groovy’s dynamic typing with def, don’t worry – the examples below are simple.
10 Practical Switch Statement Examples
Example 1: Basic Switch with Integers
What we’re doing: Matching a simple integer value – the classic switch use case.
Example 1: Basic Integer Switch
def dayNumber = 3
switch (dayNumber) {
case 1:
println "Monday"
break
case 2:
println "Tuesday"
break
case 3:
println "Wednesday"
break
case 4:
println "Thursday"
break
case 5:
println "Friday"
break
case 6:
println "Saturday"
break
case 7:
println "Sunday"
break
default:
println "Invalid day number: ${dayNumber}"
}
Output
Wednesday
What happened here: This looks identical to Java. The value 3 matches case 3:, so it prints “Wednesday.” Notice the break statements – they’re optional in Groovy because there’s no fall-through, but many developers include them out of habit or for readability. Either way is fine.
Example 2: Switch with Strings
What we’re doing: Matching string values – something Java only got in version 7.
Example 2: String Switch
def command = "deploy"
switch (command) {
case 'start':
println "Starting the application..."
break
case 'stop':
println "Stopping the application..."
break
case 'restart':
println "Restarting the application..."
break
case 'deploy':
println "Deploying new version..."
break
case 'status':
println "Checking application status..."
break
default:
println "Unknown command: '${command}'"
println "Available: start, stop, restart, deploy, status"
}
Output
Deploying new version...
What happened here: String matching works naturally in Groovy’s switch. Behind the scenes, it’s calling 'deploy'.isCase(command), which uses equals(). This is a clean pattern for building simple command parsers – far more readable than a chain of if-else blocks.
Example 3: Switch with Ranges
What we’re doing: Matching values against ranges – a feature unique to Groovy’s switch.
Example 3: Range Switch
def score = 82
switch (score) {
case 90..100:
println "Grade: A (Excellent)"
break
case 80..89:
println "Grade: B (Good)"
break
case 70..79:
println "Grade: C (Average)"
break
case 60..69:
println "Grade: D (Below Average)"
break
case 0..59:
println "Grade: F (Fail)"
break
default:
println "Invalid score: ${score}"
}
// Also works with negative ranges and characters
def letter = 'M'
switch (letter) {
case 'A'..'F':
println "${letter} is in the first group (A-F)"
break
case 'G'..'N':
println "${letter} is in the second group (G-N)"
break
case 'O'..'Z':
println "${letter} is in the third group (O-Z)"
break
}
Output
Grade: B (Good) M is in the second group (G-N)
What happened here: Ranges in case statements call Range.isCase(), which checks if the switch value falls within the range using contains(). The score 82 falls in the range 80..89, and the letter ‘M’ falls in 'G'..'N'. In Java, you’d need multiple case labels or an if-else chain for this. In Groovy, it’s one line. If you’ve used ranges with Groovy for loops, the syntax here is identical.
Example 4: Switch with Regex Patterns
What we’re doing: Matching input against regular expression patterns.
Example 4: Regex Switch
def input = "user@example.com"
switch (input) {
case ~/\d+/:
println "'${input}' is a number"
break
case ~/[a-zA-Z]+/:
println "'${input}' is a plain word"
break
case ~/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/:
println "'${input}' is an email address"
break
case ~/https?:\/\/.+/:
println "'${input}' is a URL"
break
default:
println "'${input}' is unrecognized"
}
// Test with different inputs
["42", "hello", "https://technoscripts.com"].each { val ->
switch (val) {
case ~/\d+/:
println "'${val}' -> number"
break
case ~/[a-zA-Z]+/:
println "'${val}' -> word"
break
case ~/https?:\/\/.+/:
println "'${val}' -> URL"
break
}
}
Output
'user@example.com' is an email address '42' -> number 'hello' -> word 'https://technoscripts.com' -> URL
What happened here: The ~/ / operator creates a compiled java.util.regex.Pattern. When used as a case value, it calls Pattern.isCase(), which tests if the switch value matches the entire pattern. This is incredibly useful for input validation and routing. Try doing this in Java’s switch – you can’t.
Example 5: Switch with Class Types (instanceof)
What we’re doing: Matching values by their class type – replacing verbose instanceof chains.
Example 5: Class Type Switch
def processValue(value) {
switch (value) {
case String:
println "String: '${value}' (length: ${value.length()})"
break
case Integer:
println "Integer: ${value} (doubled: ${value * 2})"
break
case BigDecimal:
println "BigDecimal: ${value} (rounded: ${value.setScale(2, BigDecimal.ROUND_HALF_UP)})"
break
case List:
println "List: ${value} (size: ${value.size()})"
break
case Map:
println "Map: ${value} (keys: ${value.keySet()})"
break
case null:
println "Got null!"
break
default:
println "Unknown type: ${value.getClass().simpleName}"
}
}
processValue("Groovy")
processValue(42)
processValue(3.14159)
processValue([1, 2, 3])
processValue([name: 'Alice', age: 30])
processValue(null)
Output
String: 'Groovy' (length: 6) Integer: 42 (doubled: 84) BigDecimal: 3.14159 (rounded: 3.14) List: [1, 2, 3] (size: 3) Map: [name:Alice, age:30] (keys: [name, age]) Got null!
What happened here: When you use a class name like String or List as a case value, Groovy calls Class.isCase(), which internally uses isInstance(). That’s equivalent to instanceof but far cleaner. Notice how we can also match null directly. This pattern is perfect for methods that accept dynamically typed parameters using def.
Example 6: Switch with Closures
What we’re doing: Using closures as case conditions for custom matching logic.
Example 6: Closure Switch
def temperature = 35
switch (temperature) {
case { it < 0 }:
println "${temperature}°C: Freezing! Stay indoors."
break
case { it >= 0 && it < 15 }:
println "${temperature}°C: Cold. Wear a jacket."
break
case { it >= 15 && it < 25 }:
println "${temperature}°C: Pleasant weather."
break
case { it >= 25 && it < 35 }:
println "${temperature}°C: Warm. Stay hydrated."
break
case { it >= 35 }:
println "${temperature}°C: Hot! Avoid direct sunlight."
break
}
// Closures with complex conditions
def password = "MyP@ss2026"
switch (password) {
case { it.length() < 8 }:
println "Password too short (min 8 characters)"
break
case { !(it ==~ /.*[A-Z].*/) }:
println "Password needs at least one uppercase letter"
break
case { !(it ==~ /.*[0-9].*/) }:
println "Password needs at least one digit"
break
case { !(it ==~ /.*[!@#\$%^&*].*/) }:
println "Password needs at least one special character"
break
default:
println "Password '${password}' is strong!"
}
Output
35°C: Hot! Avoid direct sunlight. Password 'MyP@ss2026' is strong!
What happened here: This is where Groovy’s switch really shines. Closures as case values receive the switch variable as it and return true or false. The first closure that returns true wins. This lets you express arbitrarily complex conditions in a clean switch structure instead of nested if-else blocks. The password validator demonstrates how you can build sequential validation rules.
Example 7: Switch with Lists (in)
What we’re doing: Matching a value against a list of options – like SQL’s IN clause.
Example 7: List Switch
def fruit = "mango"
switch (fruit) {
case ['apple', 'pear', 'cherry']:
println "${fruit} is a temperate fruit"
break
case ['mango', 'papaya', 'guava', 'pineapple']:
println "${fruit} is a tropical fruit"
break
case ['orange', 'lemon', 'lime', 'grapefruit']:
println "${fruit} is a citrus fruit"
break
case ['blueberry', 'strawberry', 'raspberry']:
println "${fruit} is a berry"
break
default:
println "${fruit} is not in our catalog"
}
// Multiple values per case - numbers example
def httpMethod = "PATCH"
switch (httpMethod) {
case ['GET', 'HEAD', 'OPTIONS']:
println "${httpMethod}: Safe method (no side effects)"
break
case ['POST', 'PUT', 'PATCH']:
println "${httpMethod}: Unsafe method (modifies resources)"
break
case ['DELETE']:
println "${httpMethod}: Destructive method"
break
default:
println "${httpMethod}: Unknown HTTP method"
}
Output
mango is a tropical fruit PATCH: Unsafe method (modifies resources)
What happened here: When you use a List as a case value, Groovy calls List.isCase(), which checks if the switch value is contained in the list using contains(). This is the Groovy equivalent of having multiple case labels on one line in Java, but far more expressive. You can group related values together naturally.
Example 8: Multiple Case Values (Combined Matching)
What we’re doing: Mixing different case types in a single switch statement.
Example 8: Mixed Case Types
def classify(value) {
def result
switch (value) {
case null:
result = "null value"
break
case 0:
result = "zero"
break
case 1..9:
result = "single digit (${value})"
break
case Integer:
result = "integer (${value})"
break
case ~/^[A-Z]+$/:
result = "uppercase text (${value})"
break
case String:
result = "string (${value})"
break
case [true, false]:
result = "boolean (${value})"
break
case { it instanceof List && it.size() > 3 }:
result = "big list (size: ${value.size()})"
break
case List:
result = "small list (size: ${value.size()})"
break
default:
result = "something else: ${value}"
}
return result
}
println classify(null)
println classify(0)
println classify(7)
println classify(42)
println classify("HELLO")
println classify("hello world")
println classify(true)
println classify([1, 2])
println classify([1, 2, 3, 4, 5])
Output
null value zero single digit (7) integer (42) uppercase text (HELLO) string (hello world) boolean (true) small list (size: 2) big list (size: 5)
What happened here: This example shows the real power of Groovy’s switch – mixing value matching, ranges, regex, type checking, list membership, and closures all in one statement. The order matters here: more specific cases should come before general ones. For instance, case 0 and case 1..9 come before case Integer, because otherwise every integer would match the type check first.
Example 9: Switch with Enums
What we’re doing: Using switch with enum types for type-safe pattern matching.
Example 9: Enum Switch
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
def currentSeason = Season.AUTUMN
switch (currentSeason) {
case Season.SPRING:
println "Spring: Time for gardening!"
break
case Season.SUMMER:
println "Summer: Beach time!"
break
case Season.AUTUMN:
println "Autumn: Enjoy the foliage!"
break
case Season.WINTER:
println "Winter: Stay warm!"
break
}
// Enums with ranges (yes, this works!)
enum Priority {
LOW, MEDIUM, HIGH, CRITICAL
}
def taskPriority = Priority.HIGH
switch (taskPriority) {
case Priority.LOW..Priority.MEDIUM:
println "${taskPriority}: Handle during normal hours"
break
case Priority.HIGH..Priority.CRITICAL:
println "${taskPriority}: Needs immediate attention!"
break
}
Output
Autumn: Enjoy the foliage! HIGH: Needs immediate attention!
What happened here: Enums work naturally with switch, just like in Java. But the second part shows something Java can’t do – enum ranges. Since Groovy enums support the .. range operator (based on ordinal values), you can group adjacent enum values with a range. Priority.HIGH..Priority.CRITICAL covers both HIGH and CRITICAL.
Example 10: Switch as an Expression (Return Value)
What we’re doing: Using switch as an expression that returns a value – no need for a separate variable.
Example 10: Switch as Expression
def getSeasonEmoji(month) {
def result = switch (month) {
case [12, 1, 2] -> "Winter"
case [3, 4, 5] -> "Spring"
case [6, 7, 8] -> "Summer"
case [9, 10, 11] -> "Autumn"
default -> "Unknown"
}
return result
}
(1..12).each { m ->
println "Month ${String.valueOf(m).padLeft(2)}: ${getSeasonEmoji(m)}"
}
println ""
// Classic assignment pattern (works in all Groovy versions)
def statusCode = 404
def message
switch (statusCode) {
case 200: message = "OK"; break
case 201: message = "Created"; break
case 301: message = "Moved Permanently"; break
case 400: message = "Bad Request"; break
case 401: message = "Unauthorized"; break
case 403: message = "Forbidden"; break
case 404: message = "Not Found"; break
case 500: message = "Internal Server Error"; break
default: message = "Unknown Status"
}
println "HTTP ${statusCode}: ${message}"
Output
Month 1: Winter Month 2: Winter Month 3: Spring Month 4: Spring Month 5: Spring Month 6: Summer Month 7: Summer Month 8: Summer Month 9: Autumn Month 10: Autumn Month 11: Autumn Month 12: Winter HTTP 404: Not Found
What happened here: The first function uses Groovy’s switch expression syntax with the arrow (->) operator, which returns a value directly. This is available in Groovy 4+ and makes switch behave like an expression rather than a statement. The second example shows the classic pattern that works in all Groovy versions – assign to a variable inside each case branch. Both are perfectly valid; use whichever fits your Groovy version and style preference.
Groovy Switch vs Java Switch
Let’s put the differences side by side so you can see exactly what Groovy brings to the table:
| Feature | Java Switch | Groovy Switch |
|---|---|---|
| Matched types | int, String, enum (Java 7+) | Any object |
| Range matching | Not supported | case 1..10: |
| Regex matching | Not supported | case ~/pattern/: |
| Type checking | Not supported | case String: |
| Closure conditions | Not supported | case { it > 5 }: |
| List membership | Not supported | case [1, 3, 5]: |
| Fall-through | Yes (by default) | No (by default) |
| Break required | Yes (to prevent fall-through) | No (optional) |
| Extensible via isCase() | No | Yes |
| Null handling | NullPointerException | case null: works |
Switch vs If-Else Comparison
// The if-else equivalent of Example 3's range switch
def score = 82
// Method 1: Switch (clean)
switch (score) {
case 90..100: println "Switch: Grade A"; break
case 80..89: println "Switch: Grade B"; break
case 70..79: println "Switch: Grade C"; break
case 60..69: println "Switch: Grade D"; break
case 0..59: println "Switch: Grade F"; break
}
// Method 2: If-else (verbose)
if (score >= 90 && score <= 100) {
println "If-Else: Grade A"
} else if (score >= 80 && score <= 89) {
println "If-Else: Grade B"
} else if (score >= 70 && score <= 79) {
println "If-Else: Grade C"
} else if (score >= 60 && score <= 69) {
println "If-Else: Grade D"
} else if (score >= 0 && score <= 59) {
println "If-Else: Grade F"
}
Output
Switch: Grade A If-Else: Grade A
The switch version is noticeably shorter and more readable. When you have more than three conditions, especially with ranges or type checks, switch almost always wins over if-else in both clarity and conciseness.
How isCase() Powers the Switch
Understanding isCase() is the key to truly mastering Groovy’s switch. Every case comparison calls caseValue.isCase(switchValue). You can even define your own isCase() method to create custom matchers.
Custom isCase() Implementation
// Define a custom class with isCase()
class Between {
Number low, high
Between(Number low, Number high) {
this.low = low
this.high = high
}
boolean isCase(Number value) {
return value >= low && value <= high
}
String toString() { "${low}..${high}" }
}
def age = 25
switch (age) {
case new Between(0, 12):
println "Child"
break
case new Between(13, 17):
println "Teenager"
break
case new Between(18, 64):
println "Adult"
break
case new Between(65, 150):
println "Senior"
break
}
// Verify isCase() is what drives the switch
println ""
println "Verifying isCase() calls:"
println " (1..10).isCase(5): ${(1..10).isCase(5)}"
println " (1..10).isCase(15): ${(1..10).isCase(15)}"
println " String.isCase('hi'): ${String.isCase('hi')}"
println " String.isCase(42): ${String.isCase(42)}"
println " [1,2,3].isCase(2): ${[1,2,3].isCase(2)}"
println " [1,2,3].isCase(5): ${[1,2,3].isCase(5)}"
println " (~~/\\d+/).isCase('42'): ${(~/\d+/).isCase('42')}"
Output
Adult
Verifying isCase() calls:
(1..10).isCase(5): true
(1..10).isCase(15): false
String.isCase('hi'): true
String.isCase(42): false
[1,2,3].isCase(2): true
[1,2,3].isCase(5): false
(~~/\d+/).isCase('42'): true
By implementing isCase() on your own classes, you can make them work directly in switch statements. The Groovy GDK documentation for isCase() covers all the built-in implementations.
Real-World Use Cases
Command Parsing
A common real-world scenario: parsing CLI-style commands with arguments.
Real-World: Command Parser
def parseCommand(String input) {
def parts = input.trim().split(/\s+/)
def cmd = parts[0].toLowerCase()
def args = parts.length > 1 ? parts[1..-1] : []
switch (cmd) {
case 'help':
println "Available commands: help, list, add, remove, search"
break
case 'list':
println "Listing all items..."
break
case ['add', 'create', 'new']:
println "Adding item: ${args.join(' ')}"
break
case ['remove', 'delete', 'rm']:
println "Removing item: ${args.join(' ')}"
break
case ~/search|find|query/:
println "Searching for: ${args.join(' ')}"
break
case { it.startsWith('!') }:
println "Running shell command: ${input.substring(1)}"
break
default:
println "Unknown command: '${cmd}'. Type 'help' for options."
}
}
parseCommand("help")
parseCommand("add New Task")
parseCommand("rm Old Task")
parseCommand("find groovy tutorials")
parseCommand("!ls -la")
parseCommand("unknown")
Output
Available commands: help, list, add, remove, search Adding item: New Task Removing item: Old Task Searching for: groovy tutorials Running shell command: ls -la Unknown command: 'unknown'. Type 'help' for options.
HTTP Status Code Handling
A practical example that combines ranges and specific values for handling HTTP responses.
Real-World: HTTP Status Handler
def handleResponse(int statusCode, String body = "") {
switch (statusCode) {
case 200:
println "[OK] Success: ${body.take(50)}"
break
case 201:
println "[CREATED] Resource created successfully"
break
case 204:
println "[NO CONTENT] Operation completed"
break
case 301:
case 302:
println "[REDIRECT] Resource moved (${statusCode})"
break
case 400:
println "[BAD REQUEST] Check your input parameters"
break
case 401:
println "[UNAUTHORIZED] Authentication required"
break
case 403:
println "[FORBIDDEN] Insufficient permissions"
break
case 404:
println "[NOT FOUND] Resource does not exist"
break
case 405..499:
println "[CLIENT ERROR] Error ${statusCode}: Check request"
break
case 500:
println "[SERVER ERROR] Internal server error"
break
case 501..599:
println "[SERVER ERROR] Error ${statusCode}: Try again later"
break
default:
println "[UNKNOWN] Unexpected status: ${statusCode}"
}
}
handleResponse(200, '{"users": [{"name": "Alice"}, {"name": "Bob"}]}')
handleResponse(201)
handleResponse(301)
handleResponse(404)
handleResponse(429)
handleResponse(500)
handleResponse(503)
Output
[OK] Success: {"users": [{"name": "Alice"}, {"name": "Bob"}]}
[CREATED] Resource created successfully
[REDIRECT] Resource moved (301)
[NOT FOUND] Resource does not exist
[CLIENT ERROR] Error 429: Check request
[SERVER ERROR] Internal server error
[SERVER ERROR] Error 503: Try again later
This pattern handles specific status codes individually and catches entire ranges for everything else. The range 405..499 acts as a catch-all for client errors that don’t have specific handlers. You’ll see this kind of switch in HTTP client wrappers, API integrations, and web application controllers.
No Fall-Through by Default
One of the most common sources of bugs in Java switch statements is accidental fall-through – forgetting a break and having execution flow into the next case. Groovy eliminates this entirely.
No Fall-Through Behavior
def x = 2
// In Groovy, only the matching case executes
switch (x) {
case 1:
println "One"
// no break needed - won't fall through
case 2:
println "Two"
// no break needed - won't fall through
case 3:
println "Three"
// no break needed - won't fall through
}
println ""
// In Java, the same code without break would print:
// Two
// Three <-- accidental fall-through!
//
// In Groovy, it only prints:
// Two
Output
Two
Groovy automatically breaks after the first matching case block executes. If you need multiple cases to execute the same code, use a list: case [1, 2, 3]: instead of relying on fall-through. This design choice prevents an entire category of bugs while keeping the code clean.
Edge Cases and Best Practices
Best Practices Summary
DO:
- Place more specific cases before general ones (value before range before type)
- Always include a
defaultcase for unexpected values - Use lists (
case ['a', 'b', 'c']:) instead of fall-through for grouping - Use ranges for numeric or character intervals
- Use closures for complex conditions that don’t fit other case types
DON’T:
- Put general type cases (like
case Object:) before specific value cases – they’ll catch everything - Rely on fall-through behavior from Java – it doesn’t work the same way in Groovy
- Use switch for simple binary conditions – a ternary or if-else is cleaner for that
- Forget that case order matters – the first matching case wins
Watch Out: Case Order Matters
Case Order Gotcha
def value = 5
// WRONG order - Integer catches everything before the range
switch (value) {
case Integer:
println "Wrong: Integer matched first"
break
case 1..10:
println "This will never run for integers!"
break
}
println ""
// CORRECT order - specific first, general last
switch (value) {
case 1..10:
println "Correct: Range matched first (${value} is in 1..10)"
break
case Integer:
println "Fallback for other integers"
break
}
Output
Wrong: Integer matched first Correct: Range matched first (5 is in 1..10)
Always order your cases from most specific to most general. Think of it like exception handling – catch the specific ones first, then the broad ones.
Conclusion
Groovy’s switch statement is one of those features that makes you wonder why other languages haven’t caught up. By leveraging the isCase() method under the hood, it transforms a basic control flow structure into a full-blown pattern matching engine. You can match values, ranges, regex patterns, types, list membership, and arbitrary conditions with closures – all in a single, clean switch block.
We covered 10 practical examples that demonstrate every matching technique Groovy offers. From basic integer and string matching to advanced combinations of ranges, regex, closures, and type checks. The real-world examples – command parsing and HTTP status handling – show how these features translate into production-ready code.
If you’re coming from Java, the two biggest things to remember are: no fall-through by default (so you can skip break), and case order matters because the first match wins. Put specific cases before general ones, always include a default, and use lists instead of fall-through for grouping.
Summary
- Groovy’s switch uses
isCase()– not justequals()– making it work with ranges, regex, types, closures, and lists - No fall-through by default eliminates an entire category of bugs from Java switch
- Case order matters – place specific cases before general ones
- You can define
isCase()on your own classes for custom matching - For grouping values, use
case [val1, val2, val3]:instead of fall-through
If you also work with build tools, CI/CD pipelines, or cloud CLIs, check out Command Playground to practice 105+ CLI tools directly in your browser — no install needed.
Up next: Groovy find() Method – Search Collections Like a Pro
Frequently Asked Questions
Does Groovy switch support fall-through like Java?
No. Groovy’s switch does not fall through by default. Each case block executes independently and exits after the matching branch completes – you don’t need break statements. If you want multiple values to trigger the same code, use a list: case ['a', 'b', 'c']: instead of relying on fall-through.
Can I use regular expressions in a Groovy switch case?
Yes. Use the pattern operator ~/regex/ as a case value. Groovy calls Pattern.isCase() which tests whether the switch value matches the entire regex pattern. For example: case ~/\d+/: matches any string that consists entirely of digits.
How does Groovy switch handle null values?
Groovy’s switch handles null gracefully. You can use case null: to explicitly match null values. Unlike Java, which throws a NullPointerException when you switch on null, Groovy will simply check each case using isCase() and match null if a case handles it – or fall to the default.
What is the isCase() method in Groovy?
isCase() is the method that powers Groovy’s switch statement. When you write case X:, Groovy calls X.isCase(switchValue) behind the scenes. Different types implement it differently – Class uses isInstance(), Range uses contains(), Pattern uses matches(), Closure calls itself, and List uses contains(). You can define isCase() on your own classes for custom matching.
Is Groovy switch faster or slower than if-else?
Performance is virtually identical for simple cases. Groovy’s switch has a slight overhead because it calls isCase() via dynamic dispatch, but this is negligible in practice. Choose switch over if-else for readability when you have more than 2-3 conditions. For performance-critical hot loops, consider using @CompileStatic or plain if-else.
Related Posts
Previous in Series: Groovy times() Loop – Repeat Tasks the Groovy Way
Next in Series: Groovy find() Method – Search Collections Like a Pro
Related Topics You Might Like:
- Groovy For Loop – Complete Guide with Examples
- Groovy def Keyword – Dynamic Typing Explained
- Groovy times() Loop – Repeat Tasks the Groovy Way
This post is part of the Groovy & Grails Cookbook series on TechnoScripts.com

No comment