问题:
我想创建一个泛型函数,它将返回strogly类型的对象.
功能:
public <T > T GetPet(AnimalKingdom allAnimals,int id) {
return (T) allAnimals.getAnimalsManager().findAnimalById(id);
}
Run Code Online (Sandbox Code Playgroud)
上面的函数将返回强类型对象或抛出错误.
用法:
GetPet<Tiger>(thisZoo,tigersId).Roar();
Run Code Online (Sandbox Code Playgroud)
来自C#背景.谷歌相同,但无法找到解决方案,似乎我需要传递功能的泛型类型才能工作.
如何在java中实现上述场景.
在Java中,您在方法名称之前显式指定泛型方法的类型参数.例如:
class Example {
public static <T> T getPet(AnimalKingdom allAnimals, int id) {
return (T)allAnimals.getAnimalsManager().findAnimalById(id);
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用:
Example.<Tiger>getPet(thisZoo, tigersId).roar();
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用类型推断:
Tiger tiger = Example.getPet(thisZoo, tigersId);
tiger.roar();
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你的getPet方法不是很安全,因为没有执行运行时检查以确保返回的对象实际上是一个实例Tiger.实际上,Java编译器会在此行上发出警告:
return (T)allAnimals.getAnimalsManager().findAnimalById(id);
Run Code Online (Sandbox Code Playgroud)
原因是因为类型擦除(T)导致转换为未检查.
为了加强您的代码,我建议进行以下更改:
class Example {
public static <T> T getPet(Class<T> clazz, AnimalKingdom allAnimals, int id) {
return clazz.cast(allAnimals.getAnimalsManager().findAnimalById(id));
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用:
Example.getPet(Tiger.class, thisZoo, tigersId).roar();
Run Code Online (Sandbox Code Playgroud)
传递类object(Tiger.class)的好处是:
<T>(再次通过类型推理).Class.cast方法添加自己的显式运行时类型检查.Java编译器警告消失,类型安全性恢复.例如,如果findAnimalById您在预期Tiger时错误地返回了Bear的实例,那么您将得到一个ClassCastException.