是否可以使用泛型方法而不在java中传递参数类型

Sac*_*van 2 java generics

问题:

我想创建一个泛型函数,它将返回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中实现上述场景.

cam*_*ecc 6

在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)的好处是:

  1. 它为编译器提供了用于的类型<T>(再次通过类型推理).
  2. 您可以通过调用Class.cast方法添加自己的显式运行时类型检查.Java编译器警告消失,类型安全性恢复.例如,如果findAnimalById您在预期Tiger时错误地返回了Bear的实例,那么您将得到一个ClassCastException.