Groovy Operators

Control Statements

Groovy File Handling

Groovy Error & Exceptions

Groovy Multithreading

Groovy Synchronization

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]
Advertisements