2017-08-07 12 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中,但正如我所說的,我認爲它有點春天。