2013-06-25 23 views
1

我想使用枚举实现基本状态机;枚举实现一个接口来管理允许的状态转换。但是我想在属性文件中配置一个实现接口的枚举类名列表,并且应该在特定的上下文中使用。上下文在运行时确定,并且该上下文键映射到属性文件中的属性键。一旦我从属性文件中获取上下文的枚举类名称,如何使用该类名称来获取实例引用以通过接口方法使用该枚举?我可以看到您可以使用反射来发现特定枚举的属性,但就是这样。有任何想法吗?获取对从枚举类名实现接口的Java Enum的引用

+0

如果你只有类的名字,则需要使用反射...查看该SO关于使用反射与枚举http://stackoverflow.com/questions/140537/how-to-use -java-reflection-when-the-enum-type-a-class – fmodos

+0

使用枚举类名称会破坏使用枚举的目的。枚举权力来自于引用代码中的实例名称。如果你想要使用类名,请显示一个伪代码行,即使它不能编译,所以我们知道你的意图是什么。 – Bohemian

+0

我正在使用枚举作为一个迷你状态机。 Enum实现了一个接口,该接口有一个方法getNextAllowedStates,它返回一组相同类型的Enum常量。但是我的应用程序具有服务的概念,并且取决于哪个服务请求来自我想要的状态机实现,因为每个服务的状态转换是不同的。我想只做一些事情 - 请求是服务x获取枚举类型y或服务获取枚举类型t时。这将从客户端调用的工厂完成,然后使用接口类型来获得下一个可能的状态 – PaulG

回答

1

你说得对使用反射:

  1. 使用Class.forName得到适当的Class对象,一旦你从你的属性文件读取的类名。确保您传入完全合格的课程名称。你需要在这里找到各种检查过的异常。

  2. 确保它是一个实现你的接口,与isEnum方法,并使用从接口的Class对象isAssignableFrom方法的枚举。

    isEnum()& & YourInterface.class.isAssignableFrom(clazz所)

  3. 使用静态Enum.valueOf方法从String得到实际的枚举常量,并将其投放到您的接口。

    (YourInterface) Enum.valueOf(clazz, stringName) 
    
1

我写了这...它可以帮助你:

public class MyTests { 

    static enum XX implements Runnable { 
    A, B; 
    public void run() { 
     System.out.println("I'm enum value: " + this.name()); 
    } 
    } 

    public static void main(String[] args) throws Exception { 
    new MyTests(); 
    } 

    public MyTests() throws Exception { 
    Class<?> loaded = Class.forName("MyTests$XX"); 
    Class<? extends Runnable> xx = loaded.asSubclass(Runnable.class); 
    Runnable[] enumConstants = xx.getEnumConstants(); 
    for (Runnable runnable : enumConstants) { 
     runnable.run(); 
    } 
    } 

} 

这将打印:

I'm enum value: A 
I'm enum value: B 
+0

采用确保正确类型的'asSubclass()'调用来取代不安全转换(实际上是非操作)的自由。 – erickson

+0

如果“加载”不是正确的参数化类型,你会不会在任何情况下得到一个异常?此外,你忘了删除铸造代码:) – Renato

+1

哎呀,对不起。是的,您将按照您的方式获得ClassCastException,但是稍后会在不同位置执行代码中不存在转换。在不同的上下文中,这些不安全的强制转换会在某些遥远且不相关的代码中引发神秘的'ClassCastException'错误。泛型的唯一要点是提供静态类型安全保证。但是,如果您忽略警告,则保修无效。 – erickson