java - 如何在 Java 中继承泛型静态方法?
问题描述
10 多年前,我问过这个关于 C# 的问题,并在那里得到了很好的答案。现在我正在尝试在 Java 中做同样的事情。
假设我有一个抽象类Animal
。我想要该类中的静态方法create()
,它将返回子类的类型的值。我使用以下结构在 C# 中管理它:
public class Animal<T> where T : Animal<T>, new()
{
public static T Create()
{
var t = new T();
// do generic stuff on the new T instance
return t;
}
}
public class Dog : Animal<Dog>
{
}
//usage:
var dog = Dog.Create();
这在 C# 中很有魅力。但现在我正试图在 Java 中复制这种结构,并且碰壁了。一大堵墙是您似乎不能拥有静态通用成员。因此,这似乎有点引人注目。但我是一个乐观的人,也许那里的一些 Java 专家已经提出了一个完全开箱即用的模式来或多或少地实现我在这里尝试做的事情?
解决方案
问题是在 Java 中你不能像这样从类型变量中构造一个实例。
作为一种快速的替代方法,您可以使用您的代码通过具体的构造函数调用来辅助的工厂
@FunctionalInterface
interface AnimalFactory<T extends Animal> {
T create();
static <U extends Animal> AnimalFactory<U> ofClass(Class<U> type) {
return () -> {
try {
return type.newInstance();
} catch (Exception e) {
// handle
throw new RuntimeException(e);
}
};
}
static <U extends Animal> AnimalFactory<U> ofSupplier(Supplier<U> creator) {
return creator::get;
}
}
然后你可以在你的Animal
静态方法中调用它(你确实可以将它重用于其他类型):
class Animal {
static <T extends Animal> T create(Class<T> type) {
T instance = AnimalFactory.ofClass(type)
.create();
// do generic stuff on the new T instance
return instance;
}
static <T extends Animal> T create(Supplier<T> creator) {
T instance = AnimalFactory.ofSupplier(creator)
.create();
// do generic stuff on the new T instance
return instance;
}
}
最后,您的调用代码如下所示。我使用了 lambda 和基于反射的方法。你选。
Dog d = Animal.create(Dog.class);
Dog e = Animal.create(Dog::new);
当然,您可以完全跳过静态方法Animal
并AnimalFactory
直接使用(接口现在可以具有可用于运行// do generic stuff on the new T instance
逻辑的静态方法)
推荐阅读
- reactjs - 使用 Jest 在 jsdom 中设置 baseurl 以测试 React 组件给出错误
- android - Xamarin.Forms:Xamarin Essentials GetLocation() 在 Android 11 上运行时始终返回 null
- rust - 如何将对任何类型的引用转换为对长度为 1 的数组的引用?
- javascript - 如何在 Highcharts 中隐藏类别中的空堆积列?
- c# - MS Bot ThumbnailCard 在 Facebook Messenger 上抛出错误
- stm32f4 - FATFS与定时器中断STM32f407VG冲突
- file-upload - (反应管理员)如何以二进制格式上传图像?
- cron - 有没有可以运行二级crontab的Linux包
- c++ - C++20 中反射的当前状态
- python - 如何将 Python 函数转换为 SymPy?