2012-08-03 105 views
1

有人在几分钟之前问过一个问题,因为它被低估了而被召回。很明显,枚举本身不是通用的,但问题标题是“通用枚举法”,当然可能。原来的问题有这样的东西去像一些样品伪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. 
    } 
} 

我reasking,因为我有一个潜在的答案下面,什么可能是问题背后从@Radu问题。

回答

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。

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

+0

感谢您的回答。事实上,很多事情都可以通过反思来完成,但是我一直在寻找一种优雅而安全的方式,并受到语言的支持......当反思需要做某件事情时,往往表明语言支持失败。 – rid 2012-08-03 04:21:56

+0

@Radu:当语言说不可能的时候,我认为只有可能的方法可以使用反射。 – kosa 2012-08-03 04:40:37