【发布时间】:2014-03-14 13:18:23
【问题描述】:
我有一个方法createFoo(),它使用Class<T> 实例为T 创建Foo<T> 的实例。现在我想扩展该方法以将使用枚举类型进行的调用转发到方法createEnumFoo()。从第一种方法调用第二种方法似乎并不简单。下面是一个示例,说明我如何使用两个未经检查的强制转换和一个额外的方法来做到这一点,我想摆脱所有这些。
方法castEnumType() 是必需的,因为我找不到将Class<?> 转换为Class<E extends Enum<E>> 的方法,而无需在某处绑定E。这涉及未经检查的演员表,因为我还没有找到使用Class.asSubclass() 的方法。创建Foo 的实例后,我需要将其从Foo<E> 转换为Foo<T> 事件,尽管E 和T 将始终是相同的类型。
我不能削弱createEnumFoo() 的签名,因为它正在调用Enum.valueOf(enumType, ...),并且要求其结果为E 类型。
final class Example {
<E extends Enum<E>> Foo<E> createEnumFoo(Class<E> enumType) {
// This makes use of e.g. Enum.valueOf(enumType, ...).
return null;
}
<E extends Enum<E>> Class<E> castEnumType(Class<?> enumType) {
return (Class<E>) enumType;
}
<T> Foo<T> createFoo(Class<T> type) {
if (Enum.class.isAssignableFrom(type))
return (Foo<T>) createEnumFoo(castEnumType(type));
else
// Here we would do something else or maybe throw an exception.
return null;
}
interface Foo<T> {
}
}
有没有更简单的方法来做到这一点?
一些上下文
为了澄清我面临的问题,我将解释这个问题是如何在我正在从事的项目中实际出现的:
在我遇到这个问题的代码中,Foo<T> 实际上是Converter<T>,它是一个允许T 的实例在JSON 值:
public interface Converter<T> {
JsonObject encode(T value);
T decode(JsonObject data);
}
而createFoo() 实际上是一个方法converterForType(),它采用Class<T> 实例并动态分派到一组静态方法和字段,这些静态方法和字段为常见的Java 类型和特定于项目的类型创建/包含转换器。通常当需要转换器时,直接访问适当的方法/字段,但有些地方只有在运行时才知道类型,这就是使用converterForType()的地方。
现在我想扩展该方法以通过将枚举类型转换为包含枚举常量名称的 JSON 字符串来自动处理枚举类型。这就是为什么我需要从converterForType() 调用方法enumConverter()。这是enumConverter()的实现:
public static <E extends Enum<E>> Converter<E> enumConverter(final Class<E> enumClass) {
return new Converter<E>() {
public JsonObject encode(E value) {
return Json.convert(value.name());
}
public E decode(JsonObject data) {
return Enum.valueOf(enumClass, data.asString());
}
};
}
【问题讨论】:
-
我不确定有没有更好的方法。请参阅此相关帖子:Passing a runtime resolved parameter to a method which has multiple bound type, compilation error。但是,您实际上是如何返回枚举实例的?视情况而定,您可以只使用
Class.getEnumConstants()。让我知道我是否应该用答案对此进行扩展。 -
你能展示一个使用 Enum 类创建
Foo的例子吗? -
@PaulBellora @Radiodef 我添加了一个关于这个问题在项目中实际出现的位置的描述。如果我直接调用
enumConverter(),从给定的Class<E>实例访问枚举常量不是问题。
标签: java generics casting enums