从Enum类名获取对实现接口的Java Enum的引用

从Enum类名获取对实现接口的Java Enum的引用,java,Java,我想使用enum实现一个基本状态机;枚举实现一个接口来管理允许的状态转换。但是我想在属性文件中配置实现接口的枚举的类名列表,这些枚举应该在特定上下文中使用。上下文在运行时确定,并且该上下文键映射到属性文件中的属性键。从属性文件中获取上下文的枚举类名后,如何使用该类名获取实例引用以通过接口方法使用该枚举?我可以看出,您可以使用反射来发现特定枚举的属性,但仅此而已。有什么想法吗 关于使用反射,您是对的: 从属性文件中读取类名后,使用获取适当的类对象。确保传入完全限定的类名。您需要在这里捕获各种已检查

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

关于使用反射,您是对的:

  • 从属性文件中读取类名后,使用获取适当的
    对象。确保传入完全限定的类名。您需要在这里捕获各种已检查的异常

  • 确保它是实现接口的枚举,使用
    isEnum
    方法,并使用接口的
    对象中的
    isAssignableFrom
    方法

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

  • 使用静态方法从
    字符串
    中获取实际的枚举常量,并将其强制转换到您的接口

    (YourInterface) Enum.valueOf(clazz, stringName)
    

  • 我写了这个。。。它可能会帮助您:

    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();
        }
      }
    
    }
    

    不要对那些东西进行软编码,除非你真的需要


    如果您只有类名,则需要使用反射。。。检查此项,以便使用枚举类名对枚举使用反射会违背使用枚举的目的。枚举的威力来自于在代码中引用实例名称。请给出一行伪代码,说明您希望如何使用类名,即使它没有编译,所以我们理解您的意图。Enum实现一个接口,该接口有一个方法getNextAllowedStates,该方法返回一组相同类型的Enum常量。但是我的应用程序有一个服务的概念,根据来自哪个服务的请求,我需要一个不同的状态机实现,因为每个服务的状态转换是不同的。我只想做一些类似的事情-请求是服务x获取枚举类型y,或者当服务s获取枚举类型t时。这将从客户端调用的工厂中完成,然后使用接口类型获取下一个可能的状态,这样就可以自由地使用确保类型正确的
    asSubclass()
    调用替换不安全的强制转换(实际上是一个no op)。如果“loaded”不是正确的参数化类型,在这两种情况下都不会出现异常吗?另外,你忘了删除演员代码:)哦,很抱歉。是的,您将得到一个ClassCastException,就像您得到它的方式一样,但它将在以后的不同位置,在代码中不存在强制转换。在另一种情况下,这些不安全的强制转换可能会在一些遥远且不相关的代码中引发神秘的
    ClassCastException
    错误。泛型的唯一目的是提供静态类型的安全保证。但如果您忽略警告,保修无效。
    I'm enum value: A
    I'm enum value: B