java - 在不丢失类型信息的情况下将 Class<T> 转换为 Class<E extends Enum<E>> 的最简单方法

标签 java generics casting enums

我有一个方法 createFoo()创建 Foo<T> 的实例使用 Class<T>实例 T .现在我想扩展该方法以将使用枚举类型进行的调用转发给方法 createEnumFoo() .从第一个方法调用第二个方法似乎很重要。下面是我如何使用两个未经检查的转换和一个额外的方法设法做到这一点的示例,所有这些我都想摆脱。

方法castEnumType()是必需的,因为我找不到转换 Class<?> 的方法到 Class<E extends Enum<E>>没有 E绑定(bind)某处。这涉及未经检查的类型转换,因为我还没有找到使用 Class.asSubclass() 来做到这一点的方法。 .创建 Foo 的实例后,我需要从 Foo<E> 转换它至 Foo<T>虽然事件ET将始终是相同的类型。

我无法削弱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 实例的接口(interface)序列化和反序列化为 JSON 值:

public interface Converter<T> {
    JsonObject encode(T value);

    T decode(JsonObject data);
} 

createFoo()实际上是一个方法 converterForType()这需要 Class<T>实例并动态分派(dispatch)到一组静态方法和字段,这些静态方法和字段创建/包含常见 Java 类型和特定于项目的类型的转换器。通常,当需要转换器时,会直接访问适当的方法/字段,但有些地方的类型仅在运行时才知道,即 converterForType()被使用。

现在我想扩展该方法以通过将枚举类型转换为包含枚举常量名称的 JSON 字符串来自动处理枚举类型。这就是为什么我需要调用方法 enumConverter() 的原因来自 converterForType() .这是 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());
        }
    };
}

最佳答案

这个怎么样,对 createEnumFoo 方法使用原始类型
编辑:修复@Feuermurmel 在评论中报告的编译错误

@SuppressWarnings({ "unchecked", "rawtypes" })
final class Example
{
    <E extends Enum<E>> Foo<E> createEnumFoo(Class enumType)
    {
        // This makes use of e.g. Enum.valueOf(enumType, ...).
        Enum x = Enum.valueOf(enumType, "x");
        return (Foo<E>) x;
    }

    <T extends Enum> Foo<T> createFoo(Class<T> type)
    {
        if (Enum.class.isAssignableFrom(type))
            return (Foo<T>) createEnumFoo(type);
        else
            // Here we would do something else or maybe throw an exception.
            return null;
    }

    interface Foo<T>
    {
    }
}

关于java - 在不丢失类型信息的情况下将 Class<T> 转换为 Class<E extends Enum<E>> 的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22406135/

相关文章:

java - JPA/Hibernate + 从 onetomayrelation 获取特定项目

Scala 通用推理

c# - 如何比较两个通用对象与嵌套集合

java - 参数化类型是什么意思?

c++ - 将 1Byte 数据转换为 4Byte 时详细发生了什么

java - 在 Java 中不进行强制转换来表示数字

派生类的 C# 转换

java - 如何将字符串拆分为多个部分

java - double 放入数组,然后从小到大排序显示

java - 我们可以在javafx中的多个类之间创建回调吗