2017-08-07 10 views
0

考虑下面内Enum实现一个接口:爪哇 - 如何将字符串转换成特定的枚举实现一个接口

public interface NotificationTypes { 

    public enum CONTACT_LIST implements NotificationTypes{ 
     ADDED("CONTACT_LIST-ADDED"), 
     REMOVED("CONTACT_LIST-REMOVED"); 
     public enum INVITATION implements NotificationTypes{ 
      ACCEPTED("CONTACT_LIST-INVITATION-ACCEPTED"), 
      REJECTED("CONTACT_LIST-INVITATION-REJECTED"); 

      String name = ""; 
      private INVITATION(String name){ 
       this.name = name; 
      } 

      public String getName(){ 
       return name; 
      } 
     }; 

     String name = ""; 
     private CONTACT_LIST(String name){ 
      this.name = name; 
     } 

     public String getName(){ 
      return name; 
     } 
    } 
    public String getName(); 
} 

现在考虑在数据库中的数据/ MongoDB是存储在String的形式NotificationTypes在表/文件。

{ 
    "_id" : ObjectId("59882ba49e5d82c72ba44fde"), 
    "template" : "Contact list Invitation accepted by your friend", 
    "type" : "CONTACT_LIST-INVITATION-ACCEPTED" 
} 

所以我的问题是:如何该字符串转换回特定的枚举在运行时不知道枚举的名称完全映射?

域类看起来是这样的:

@Document(collection = CollectionNames.XXX_TEMPLATE) 
public class XXXTemplate { 

    private NotificationTypes type; 
    //Other parameters, getters & setters + Constructor 
} 

回答

1

我想建立一个Map<String, NotificationTypes>并填充你所拥有的所有实例。然后你可以从那张地图上查找。

我不认为编译器可以帮助你保持同步,除了你可以遍历EnumType.values()(但你必须记住为你的所有枚举类型)。

+0

好的谢谢你的回复。但如果我嵌套枚举高达3-4级,那么我必须遍历所有枚举,不是??是否有任何简短的方式来循环实现给定接口(NotificationTypes)的所有枚举? – Afridi

+1

不,您必须构建该映射(静态地,拼写出源代码中的所有类型)。但是从那张地图上查找是微不足道的。 – Thilo

+0

如果你真的想要让代码找到你的接口的所有实现:https://stackoverflow.com/questions/347248/how-can-i-get-a-list-of-all-the-implementations-of -an-interface-programmatically但是不要。住在地图上或重新考虑你的设计。 – Thilo

0

如何在运行时将该字符串转换回特定的枚举而不知道要映射的枚举的名称?

通过Enum.valueOf()

+1

但是,你需要知道它是哪种'enum'。它可以与标识符一起使用,而不是使用自定义的'name'。 – Thilo

+0

@EJP感谢您的重播。但是这种方法也需要enum类型,我不知道它是否运行。有很多内部枚举实现相同的接口。 – Afridi

+1

@Afridi然后你已经将自己设计成了一个不受该语言支持的角落。 – EJP

0

基本上只是建立在@蒂洛的答案,但也许更多的“Springified”的方式,如果它的东西,你会想 - 你可以定义你的配置包含您的所有枚举值,像@Bean

@Configuration 
public class Config { 
    @Bean 
    public List<NotificationTypes> notificationTypes() { 
     List<NotificationTypes> notificationTypes = new ArrayList<>(); 

     notificationTypes.addAll(Arrays.asList(NotificationTypes.CONTACT_LIST.values())); 
     notificationTypes.addAll(Arrays.asList(NotificationTypes.CONTACT_LIST.INVITATION.values())); 

     return notificationTypes; 
    } 
} 

然后@Autowire@Bean到解析器做字符串的实际匹配枚举,是这样的:

@Component 
public class NotificationTypeParser { 
    @Autowired 
    private List<NotificationTypes> notificationTypes; 

    public NotificationTypes parseNotificationType(String type) { 
     for (NotificationTypes notificationType : notificationTypes) { 
      if (notificationType.getName().equals(type)) { 
       return notificationType; 
      } 
     } 
     return null; 
    } 
} 

显然,你可能想要的东西不仅仅是返回更好如果未找到枚举,并且您可能会在@Bean定义中做一些更明智的事情来验证枚举是否具有不同的名称等。或者,可以想象,在那里使用反射来查找NotificationTypes的所有实现。

我不确定这真的会给你带来任何额外的好处,只是将所有可能的值存储在Map中,但正如我所说的,我认为它有点春天。