通用枚举方法

时间:2012-08-03 03:56:40

标签: java generics enums

刚才有人问了一个问题,因为它被低估了。有人清楚地指出,枚举本身不是通用的,但问题标题是“通用枚举方法”,当然可能的。原始问题有一些示例伪Java代码,类似于:

enum Test<T> {
    TEST1<T1>,
    TEST2<T2>,
    TEST3<T3>;
    // I missed some details they had here for overriding methods or such

   public T getInstance() {...
      // somehow returning a T1 when called on TEST1, a T2 for TEST2, etc.
   }
}

我正在重新研究,因为我对下面有一个潜在的答案,可能是背后的问题来自@Radu的问题。

1 个答案:

答案 0 :(得分:1)

已经提供的示例代码(我试图在上面的问题中从内存中复制,显然无法按预期工作,因为枚举本身不能是通用的。

但是根据原始海报试图完成的内容,下面的内容可能会提供正在寻找的东西,并且它可以编译和运行。

public enum Test {
    TEST1(String.class),
    TEST2(Object.class),
    ;

    Class clazz;

    Test(Class<?> clazz) {
        this.clazz = clazz;
    }

    <T> T getInstance() throws IllegalAccessException, InstantiationException {
        return (T)clazz.newInstance();
    }

    public static void main(String[] args) {
        try {
            String str = TEST1.getInstance();
            Object obj = TEST2.getInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

这里写的有一些明显的缺陷。根据您为每个枚举值提供的类型,可能没有可用的无参数构造函数。如果需要解决这个问题,可以通过使用Objenesis使其变得更加复杂。此外,我“巧妙地”使该方法的返回类型成为通用的,因此可以在没有警告/错误的情况下对其进行分配。但是,这样做完全不是类型安全的。您可以在没有编译器错误的情况下撤消分配:

String str = TEST2.getInstance();
Object obj = TEST1.getInstance();

但是你得到一个运行时ClassCastException。

在任何情况下,我认为我已经证明泛型方法可以用枚举编写,而且还可以在枚举中编写单个方法,根据静态类型返回不同类类型的新实例与每个枚举值相关联(仅作为每个枚举值的通用参数)。