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?
You could define
callFriendthis way:Then call it as such:
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.