
- Groovy Tutorial
- Groovy - Home
- Groovy - Overview
- Groovy - Environment
- Groovy - Basic Syntax
- Groovy - Data Types
- Groovy - Variables
- Groovy - Optionals
- Groovy - Numbers
- Groovy - Strings
- Groovy - Ranges
- Groovy - Lists
- Groovy - Maps
- Groovy - Dates & Times
Groovy Operators
- Groovy - Operators
- Groovy - Arithmetic Operators
- Groovy - Assignment Operators
- Groovy - Relational Operators
- Groovy - Logical Operators
- Groovy - Bitwise Operators
- Groovy - Spaceship Operator
- Groovy - in Operator
- Groovy - Elvis Operator
- Groovy - Safe Navigation Operator
- Groovy Operator Precedence & Associativity
Control Statements
- Groovy - Decision Making
- Groovy - If Else Statement
- Groovy - Switch Statement
- Groovy - Loops
- Groovy - For Loop
- Groovy - For-in Loop
- Groovy - While Loop
- Groovy - Do While Loop
- Groovy - Break Statement
- Groovy - Continue Statement
Groovy File Handling
- Groovy - File I/O
- Java - Create a File
- Java - Write to File
- Java - Append to File
- Java - Read Files
- Java - Delete Files
- Java - File Properties
- Java - File Existence and Type
- Java - File Size
- Java - File Permissions
- Java - Directories
- Java - Listing Directories
- Java - Filtering Files/Directories
- Java - Deleting Directories
- Java - Renaming Files/Directories
Groovy Error & Exceptions
- Groovy - Exception Handling
- Groovy - try-catch Block
- Groovy - try-with-resources
- Groovy - Multi-catch Block
- Groovy - Nested try Block
- Groovy - Finally Block
- Groovy - throw Exception
- Groovy - Exception Propagation
- Groovy - Built-in Exceptions
- Groovy - Custom Exception
Groovy Multithreading
- groovy - Multithreading
- groovy - Thread Life Cycle
- groovy - Creating a Thread
- groovy - Starting a Thread
- groovy - Joining Threads
- groovy - Naming Thread
- groovy - Thread Scheduler
- groovy - Thread Pools
- groovy - Main Thread
- groovy - Thread Priority
- groovy - Daemon Threads
- groovy - Shutdown Hook
Groovy Synchronization
- groovy - Synchronization
- groovy - Block Synchronization
- groovy - Static Synchronization
- groovy - Inter-thread Communication
- groovy - Thread Deadlock
- groovy - Interrupting a Thread
- groovy - Thread Control
- groovy - Reentrant Monitor
- Groovy - Methods
- Groovy - Methods
- Groovy - Optional parenthesis
- Groovy - Named Arguments
- Groovy - Closures as Arguments
- Groovy - Method Overloading
- Groovy - Method Scope and Visibility
- Groovy - isCase Method
- Groovy - Implicit Return
- Groovy - Variable Arguments
- Groovy - Regular Expressions
- Groovy - Regular Expressions
- Groovy - Defining Regular Expressions
- Groovy - Matcher Object
- Groovy - Regex Tasks
- Groovy - XML
- Groovy - XML
- Groovy - Parsing XML
- Groovy - Creating XML
- Groovy - Modifying XML
- Groovy - Querying XML
- Groovy - Simplified Notation
- Groovy - Closure based Querying
- Groovy - Closure based Creation
- Groovy - JSON
- Groovy - JSON
- Groovy - Parsing JSON
- Groovy - Creating JSON using JsonOutput
- Groovy - Creating JSON using JsonBuilder
- Groovy - Modifying JSON
- Groovy - Error Handling
- Groovy - Handling JSON Arrays
- Groovy - JSON Array Operations
- Groovy - JSON Objects
- Groovy - JSON Object Operations
- Groovy - Generics
- Groovy - Generics
- Groovy - Declaring Generic Types
- Groovy - Bound Type Parameters
- Groovy - Wild Cards
- Groovy - Miscellaneous
- Groovy - Object Oriented
- Groovy - Closures
- Groovy - Annotations
- Groovy - JMX
- Groovy - DSLS
- Groovy - Database
- Groovy - Builders
- Groovy - Command Line
- Groovy - Unit Testing
- Groovy - Template Engines
- Groovy - Meta Object Programming
- Groovy Useful Resources
- Groovy - Quick Guide
- Groovy - Useful Resources
- Groovy - Discussion
Groovy - Wild Cards in Generics
Wild Cards provides the flexibility in defining the generic type where exact type parameter is not known. There are three types of wild cards used in defining the generics.
< ? > (Unbounded) − It represents any unknown type. Generally used where we're not having any restriction for example, printing objects.
<? extends SomeClass> (upper-bounded) − It is useful while reading values from a collection, and we need to use the method of the element.
<? super SomeClass>? (lower-bounded) − It is useful while writing values to a collection and we need to write safely to the collection.
Example - Usage of < ? > (Unbounded) Wild Card
Unbounded wild card is used where we want to work with any kind of object. For example, we want to print all items of a list.
Example.groovy
void printAll(List<?> list) { for (Object item : list) { println item } } List<Integer> numbers = [1, 2, 3, 4, 5] List<String> fruits = ["mango", "apple","strawberry"] // prints all numbers printAll(numbers) // print all strings printAll(fruits)
Output
When we run the above program, we will get the following result.
1 2 3 4 5 mango apple strawberry
Example - Usage of < ? extends SomeClass> (Upper bounded) Wild Card
Upper bounded wild card is particularly useful when we need to read from a collection and to execute a certain method specific to upper bound class.
Example.groovy
class Animal { void cry() { println "Generic sound" } } class Dog extends Animal { @Override void cry() { println "Woof!" } } class Cat extends Animal { @Override void cry() { println "Meow!" } } void makeSounds(List<? extends Animal> animals) { for (Animal animal : animals) { animal.cry() // call cry as type is subclass of Animal } } List<Dog> dogs = [new Dog(), new Dog()] List<Cat> cats = [new Cat(), new Cat()] makeSounds(dogs) makeSounds(cats)
Output
When we run the above program, we will get the following result.
Woof! Woof! Meow! Meow!
Example - Usage of < ? super SomeClass> (Lower bounded) Wild Card
Lower bounded wild card is particularly useful when we need to write to a generic collection and want to allow addition of certain types of element only.
Example.groovy
class Animal { void cry() { println "Generic sound" } } class Dog extends Animal { @Override void cry() { println "Woof!" } } class Cat extends Animal { @Override void cry() { println "Meow!" } } void addPetToList(List<? super Animal> animals, Animal pet) { animals.add(pet) } List<Animal> shelter = new ArrayList<Animal>() addPetToList(shelter, new Dog()) addPetToList(shelter, new Cat()) println shelter
Output
When we run the above program, we will get the following result.
[Dog@747f281, Cat@1169afe1]