将Class <t>转换为类的最简单方法<e extends =“”enum <e =“”>&gt;不丢失类型信息</e> </t>

时间:2014-03-14 13:18:23

标签: java generics casting enums

我有一个方法createFoo(),可以使用Foo<T>的{​​{1}}实例创建Class<T>个实例。现在我想扩展该方法以将使用枚举类型进行的调用转发给方法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>的实例被序列化和反序列化的接口。一个 JSON 值:

T

public interface Converter<T> { JsonObject encode(T value); T decode(JsonObject data); } 实际上是一个方法createFoo(),它接受​​一个converterForType()实例并动态调度到一堆静态方法和字段,这些方法和字段创建/包含特定Java类型和类型的转换器到项目。通常,当需要转换器时,直接访问适当的方法/字段,但有些地方只在运行时知道类型,这是使用Class<T>的地方。

现在我想扩展该方法,通过将枚举类型转换为包含枚举常量名称的JSON字符串来自动处理枚举类型。这就是我需要从converterForType()调用方法enumConverter()的原因。这是converterForType()

的实现
enumConverter()

1 个答案:

答案 0 :(得分:1)

然后,使用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>
    {
    }
}