Sathish Sathish - 5 months ago 19
Java Question

How do I make the method return type generic?

Consider this example (typical in OOP books):

I have an

Animal
class, where each
Animal
can have many friends.

And subclasses like
Dog
,
Duck
,
Mouse
etc which add specific behavior like
bark()
,
quack()
etc.

Here's the
Animal
class:

public class Animal {
private Map<String,Animal> friends = new HashMap<>();

public void addFriend(String name, Animal animal){
friends.put(name,animal);
}

public Animal callFriend(String name){
return friends.get(name);
}
}


And here's some code snippet with lots of typecasting:

Mouse jerry = new Mouse();
jerry.addFriend("spike", new Dog());
jerry.addFriend("quacker", new Duck());

((Dog) jerry.callFriend("spike")).bark();
((Duck) jerry.callFriend("quacker")).quack();


Is there any way I can use generics for the return type to get rid of the typecasting, so that I can say

jerry.callFriend("spike").bark();
jerry.callFriend("quacker").quack();


Here's some initial code with return type conveyed to the method as a parameter that's never used.

public<T extends Animal> T callFriend(String name, T unusedTypeObj){
return (T)friends.get(name);
}


Is there a way to figure out the return type at runtime without the extra parameter using
instanceof
? Or at least by passing a class of the type instead of a dummy instance.

I understand generics are for compile time type-checking, but is there a workaround for this?

laz laz
Answer

You could define callFriend this way:

public <T extends Animal> T callFriend(String name, Class<T> type) {
    return type.cast(friends.get(name));
}

Then call it as such:

jerry.callFriend("spike", Dog.class).bark();
jerry.callFriend("quacker", Duck.class).quack();

This code has the benefit of not generating any compiler warnings. Of course this is really just an updated version of casting from the pre-generic days and doesn't add any additional safety.

Comments