Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Producer and Consumer with Generics in Java

I have this method to retrieve the objects which are instance of a given class:

public class UtilitiesClass {

    public static final Collection<Animal> get(Collection<Animal> animals, Class<? extends Animal> clazz) {
        // returns the Animals which are an instanceof clazz in animals
    }
...
}

To call the method, I can do something like this:

Collection<Animal> dogs = UtilitiesClass.get(animals, Dog.class);

That is good, but I would also like to be able to call the method in these two ways:

Collection<Animal> dogs = UtilitiesClass.get(animals, Dog.class);

or

Collection<Dog> dogsTyped = UtilitiesClass.get(animals, Dog.class);

What I mean is that I want to be able to store result of the method in a Dog Collection or in an Animal one, because Dog.class extends Animal.class

I was thinking in something like this:

public static final <T> Collection<T> get(Class<T extends Animal> clazz) {
    // returns the Animals which are an instanceof clazz
}

But it does not work. Any hint?

Edit: Finally, using @Rohit Jain answer, this is the solution when you call to the UtilitiesClass method:

Collection<? extends Animal> dogsAnimals = UtilitiesClass.get(animals, Dog.class);
Collection<Dog> dogs = UtilitiesClass.get(animals, Dog.class);
like image 984
Manuelarte Avatar asked Jan 12 '23 03:01

Manuelarte


1 Answers

Yes, you have to make the method generic. And the bounds should be given while declaring the type parameter:

public static final <T extends Animal> Collection<T> get(
                   Collection<Animal> animals, Class<T> clazz) {
}

But, while adding the animal from animals collection to a new Collection<T>, you would have to cast it back to clazz type. You would need Class#isInstance(Object) method, and also Class#cast(Object) method.

like image 64
Rohit Jain Avatar answered Jan 19 '23 17:01

Rohit Jain