问题:
我想创建一个通用函数,它将返回strogly类型的对象。
功能:
public <T > T GetPet(AnimalKingdom allAnimals,int id) {
return (T) allAnimals.getAnimalsManager().findAnimalById(id);
}
上述函数将返回强类型对象或抛出错误。
用法:
GetPet<Tiger>(thisZoo,tigersId).Roar();
来自C#背景。谷歌搜索相同,但无法找到解决方案,似乎我需要在函数中传递泛型类型才能工作。
如何在java中实现上述场景。
答案 0 :(得分:6)
在Java中,您在方法名称之前显式指定泛型方法的类型参数。例如:
class Example {
public static <T> T getPet(AnimalKingdom allAnimals, int id) {
return (T)allAnimals.getAnimalsManager().findAnimalById(id);
}
}
然后调用:
Example.<Tiger>getPet(thisZoo, tigersId).roar();
或者,您可以使用type inferencing:
Tiger tiger = Example.getPet(thisZoo, tigersId);
tiger.roar();
顺便说一句,您的getPet
方法不是很安全,因为没有执行运行时检查以确保返回的对象实际上是Tiger
的实例。实际上,Java编译器会在此行上发出警告:
return (T)allAnimals.getAnimalsManager().findAnimalById(id);
原因是由于type erasure而取消选中(T)
的广告素材。
为了加强您的代码,我建议进行以下更改:
class Example {
public static <T> T getPet(Class<T> clazz, AnimalKingdom allAnimals, int id) {
return clazz.cast(allAnimals.getAnimalsManager().findAnimalById(id));
}
}
然后调用:
Example.getPet(Tiger.class, thisZoo, tigersId).roar();
传入类对象(Tiger.class
)的好处是:
<T>
的类型(再次通过类型推理)。Class.cast
方法添加自己的显式运行时类型检查。 Java编译器警告消失,类型安全性恢复。例如,如果findAnimalById
在您预期Tiger时错误地返回了Bear的实例,那么您将获得ClassCastException
。答案 1 :(得分:1)
请尝试类似
的内容Tiger tiger = GetPet(thisZoo,tigersId);
tiger.Roar();
答案 2 :(得分:0)
在这里使用泛型只是错误的选择。你应该看一下继承,虚函数,abtract类和接口。
答案 3 :(得分:0)
正如SylvainL所说,仿制药不是这里的正确选择。这看起来像是一个简单的继承/接口问题。
新的getPet方法:
public Animal getPet(AnimalKingdom allAnimals, int id)
{
return allAnimals.getAnimalsManager().findAnimalById(id);
}
使用继承:
class Animal { void Roar() { throw new Exception("This animal cannot roar!"); } };
class Tiger extends Animal { @Override void Roar() { ... }; ... };
用法:
getPet(thisZoo, tigersId).Roar();
或使用界面:(稍微复杂但可能更好)
注意:在这种情况下你真的不需要Animal,你可以只使用Object
class Animal { ... }; // no Roar method
interface Roarer { void Roar(); };
class Tiger extends Animal implements Roarer { @Override void Roar() { ... }; ... };
注意:您可以将以下任一用法放入方法中,以便最终得到类似:
roar(getPet(thisZoo, tigersId));
用法:(您可以删除try {} catch
,但这通常不是一个好主意)
try
{
((Roarer)getPet(thisZoo, tigersId)).Roar();
}
catch (ClassCastException e) { /* handle error */ };
用法替代方法:(安全地避免try {} catch
,尚未尝试过,但我认为它可能有效)
Animal animal = getPet(thisZoo, tigersId);
if (Roarer.class.isAssignableFrom(animal.class))
((Roarer)animal).Roar();
else
// handle error