Рассмотрим этот пример (типичный для книг ООП):
У меня есть класс Animal, где у каждого Animal может быть много друзей. 
И подклассы типа Dog, Duck, Mouse и т.д., Которые добавляют определенное поведение, например bark(), quack() и т.д.
Здесь класс Animal:
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);
    }
}
И вот фрагмент кода с большим количеством типов:
Mouse jerry = new Mouse();
jerry.addFriend("spike", new Dog());
jerry.addFriend("quacker", new Duck());
((Dog) jerry.callFriend("spike")).bark();
((Duck) jerry.callFriend("quacker")).quack();
Есть ли способ использовать generics для возвращаемого типа, чтобы избавиться от typecasting, так что я могу сказать
jerry.callFriend("spike").bark();
jerry.callFriend("quacker").quack();
Здесь некоторый исходный код с возвращаемым типом передается методу в качестве параметра, который никогда не использовался.
public<T extends Animal> T callFriend(String name, T unusedTypeObj){
    return (T)friends.get(name);        
}
Есть ли способ выяснить тип возврата во время выполнения без дополнительного параметра, используя instanceof? Или, по крайней мере, путем передачи класса типа вместо фиктивного экземпляра. 
Я понимаю, что generics предназначены для проверки типа времени компиляции, но есть ли способ обхода этого пути?
