|
| 1 | +## Java 中如何将 String 转换为 enum |
| 2 | + |
| 3 | +###问题 |
| 4 | +我有一个 enum 类 |
| 5 | + |
| 6 | +``` java |
| 7 | +public enum Blah { |
| 8 | + A, B, C, D |
| 9 | +} |
| 10 | +``` |
| 11 | +我想要找到一个 `String` 对应的 enum 值。例如, `"A"` 将是 `Blah.A`.如何做到? |
| 12 | + |
| 13 | +我需要使用 `Enum.valueOf()` 方法吗? 如果是该如何使用? |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +### A1 |
| 18 | + |
| 19 | +是的, `Blah.valueOf("A")` 将会给你 `Blah.A`. |
| 20 | + |
| 21 | +静态方法 `valueof()` 和 `values()` 在编译时期被插入,并不存在于源码中。但是在Javadoc中;例如,[`Dialog.ModalityType`](http://docs.oracle.com/javase/7/docs/api/java/awt/Dialog.ModalityType.html "Dialog.ModalityType")中显示了这两个方法。 |
| 22 | + |
| 23 | + |
| 24 | +### A2 |
| 25 | + |
| 26 | +另一个解答,如果文本和 `enumeration` 值不一致 |
| 27 | + |
| 28 | +``` java |
| 29 | +public enum Blah { |
| 30 | + A("text1"), |
| 31 | + B("text2"), |
| 32 | + C("text3"), |
| 33 | + D("text4"); |
| 34 | + |
| 35 | + private String text; |
| 36 | + |
| 37 | + Blah(String text) { |
| 38 | + this.text = text; |
| 39 | + } |
| 40 | + |
| 41 | + public String getText() { |
| 42 | + return this.text; |
| 43 | + } |
| 44 | + |
| 45 | + public static Blah fromString(String text) { |
| 46 | + if (text != null) { |
| 47 | + for (Blah b : Blah.values()) { |
| 48 | + if (text.equalsIgnoreCase(b.text)) { |
| 49 | + return b; |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + return null; |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | +_评论区在讨论是应该返回null还是抛出异常,个人认为视具体情况,允许转换失败就返回null,不允许就抛出异常,或许创建一个特殊的空对象是个好的选择 -译者注_ |
| 58 | + |
| 59 | +### A3 |
| 60 | + |
| 61 | +这是我使用的一个工具类: |
| 62 | + |
| 63 | +``` java |
| 64 | +/** |
| 65 | + * 一个对于所有Enum类通用的方法,因为他们不能有另一个基类 |
| 66 | + * @param <T> Enum type |
| 67 | + * @param c enum type. All enums must be all caps. |
| 68 | + * @param string case insensitive |
| 69 | + * @return corresponding enum, or null |
| 70 | + */ |
| 71 | +public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) { |
| 72 | + if( c != null && string != null ) { |
| 73 | + try { |
| 74 | + return Enum.valueOf(c, string.trim().toUpperCase()); |
| 75 | + } catch(IllegalArgumentException ex) { |
| 76 | + } |
| 77 | + } |
| 78 | + return null; |
| 79 | +} |
| 80 | +``` |
| 81 | +之后,在我的enum类中通常如此使用来减少打字: |
| 82 | +``` java |
| 83 | +public static MyEnum fromString(String name) { |
| 84 | + return getEnumFromString(MyEnum.class, name); |
| 85 | +} |
| 86 | +``` |
| 87 | +如果的enums不是全部大写,只需要修改 `Enum.valueOf` 这一行。 |
| 88 | +很遗憾,我不能使用 `T.class` 传给 `Enum.valueOf`,因为 `T`会被擦出。 |
| 89 | + |
| 90 | +_评论区对于答主的异常处理一片指责 -译者注_ |
| 91 | + |
| 92 | +###A4 |
| 93 | +如果你不想编写自己的工具类,可以使用 Google的 `guava` 库: |
| 94 | +``` java |
| 95 | +Enums.getIfPresent(Blah.class, "A") |
| 96 | +``` |
| 97 | +它让你检查是否 `Blan`中存在 `A`并且不抛出异常 |
| 98 | + |
| 99 | +_完整方法签名 `Optional<T> getIfPresent(Class<T> enumClass, String value)` , `Optional` 对象可以优雅的解决null值问题 -译者注_ |
| 100 | + |
| 101 | +--- |
| 102 | +_其他的答案都大同小异,感兴趣的可以看原帖_ |
| 103 | +_原帖:[Convert a String to an enum in Java](http://stackoverflow.com/questions/604424/lookup-enum-by-string-value)_ |
| 104 | +_译者:[MagicWolf](https://github.com/DaiDongLiang)_ |
| 105 | + |
| 106 | + |
0 commit comments