Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override generic list return type in java

Tags:

java

generics

I am trying to override the method which return type as list in sub class like as below example, due to generics issue i can not able to do it in my sub class. I can not able to change my super class code, so how i can resolve the issue? any one can please guide me...many thanks in advance.

Super classes which can not be update:

public class Animal {
           private String legs;
    }

public class TestSuper {

    public List<Animal> addAnimals() {
        return animals;
    }
}

Sub classes:

public class Dog extends Animal {
         private String sound;
    }

public class TestSub extends TestSuper {

    public List<Dog> addAnimals() { --> I need to override this method but want return type as List of dogs
        return null;
    }
}
like image 673
Satya Avatar asked Oct 09 '13 15:10

Satya


People also ask

Can we override return type in Java?

The overriding method was said to be invariant with respect to return type. Java version 5.0 onwards it is possible to have different return types for an overriding method in the child class, but the child's return type should be a subtype of the parent's return type.

Can I change the return type in an overridden method?

Yes. It is possible for overridden methods to have different return type .

What is return type override?

Covariant return type refers to return type of an overriding method. It allows to narrow down return type of an overridden method without any need to cast the type or check the return type. Covariant return type works only for non-primitive return types.

Can you override an instance method?

An instance method that is defined in a subclass is said to override an inherited instance method that would otherwise be accessible in the subclass if the two methods have the same signature.


1 Answers

If the super classes really can't be updated, I'm afraid you simply can't.

If you had been able to update the super classes:

In TestSuper, you would have use public List<? extends Animal> addAnimals() instead of public List<Animal> addAnimals().

What other solution(s) do you have:

You could use such a utility method:

@SuppressWarnings("unchecked")
public static <T extends Animal> List<T> cast(List<Animal> animals, Class<T> subclass) {
    List<T> out = new ArrayList<T>();
    for (Animal animal : animals) {
        if (!subclass.isAssignableFrom(animal.getClass())) {
            // the "animal" entry isn't an instance of "subclass"
            // manage this case however you want ;)
        } else {
            out.add((T) animal);
        }
    }
    return out;
}

Then, to call:

List<Dog> dogs = TheClassNameYouChose.cast(animals, Dog.class);
like image 52
sp00m Avatar answered Sep 27 '22 22:09

sp00m