【问题标题】:Best way to create enum of strings?创建字符串枚举的最佳方法?
【发布时间】:2011-04-28 01:52:23
【问题描述】:

enum 类型表示一组字符串的最佳方式是什么?

我试过了:

enum Strings{
   STRING_ONE("ONE"), STRING_TWO("TWO")
}

我怎样才能将它们用作Strings

【问题讨论】:

    标签: java enums


    【解决方案1】:

    我不知道你想做什么,但这就是我实际翻译你的示例代码的方式......

    package test;
    
    /**
     * @author The Elite Gentleman
     *
     */
    public enum Strings {
        STRING_ONE("ONE"),
        STRING_TWO("TWO")
        ;
    
        private final String text;
    
        /**
         * @param text
         */
        Strings(final String text) {
            this.text = text;
        }
    
        /* (non-Javadoc)
         * @see java.lang.Enum#toString()
         */
        @Override
        public String toString() {
            return text;
        }
    }
    

    或者,您可以为text 创建一个getter 方法。

    你现在可以Strings.STRING_ONE.toString();

    【讨论】:

    • 不知道是不是编译器要求,但private String text应该是final的。
    • @Tomás Narros 是的,你仍然可以在构造函数中为其赋值,只要你在声明它为 final 时不给它一个值。
    • @The Elite Gentleman 如果枚举常量的值在运行时发生变化会很糟糕,所以即使不需要,final 也是最好的。
    • 不要忘记枚举不能用new 构造,因为构造函数是private。本质上,对象创建是被禁止的,在这种情况下final 并不是真正需要的。
    • @BuhakeSindi: 是的,但不小心可能会倾向于在枚举上放置一个setText(String),这可能会引发地狱 :) final 一种记录你的意图,即它是编译器的常量支持。如果您要使用String 常量,您不会将其声明为public static String,对吧?
    【解决方案2】:

    获取并设置默认值。

    public enum Status {
    
        STATUS_A("Status A"),  STATUS_B("Status B"),
    
        private String status;
    
        Status(String status) {
            this.status = status;
        }
    
        public String getStatus() {
            return status;
        }
    }
    

    【讨论】:

    • STATUS_B 后面需要分号(不是逗号)。
    【解决方案3】:

    你可以将它用于字符串枚举

    public enum EnumTest {
        NAME_ONE("Name 1"),
        NAME_TWO("Name 2");
    
        private final String name;
    
        /**
         * @param name
         */
        private EnumTest(final String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    

    并从主方法调用

    public class Test {
        public static void main (String args[]){
            System.out.println(EnumTest.NAME_ONE.getName());
            System.out.println(EnumTest.NAME_TWO.getName());
        }
    }
    

    【讨论】:

      【解决方案4】:

      将枚举名称设置为与您想要的字符串相同,或者更一般地说,您可以将任意属性与您的枚举值相关联:

      enum Strings {
         STRING_ONE("ONE"), STRING_TWO("TWO");
         private final String stringValue;
         Strings(final String s) { stringValue = s; }
         public String toString() { return stringValue; }
         // further methods, attributes, etc.
      }
      

      将常量放在顶部,将方法/属性放在底部很重要。

      【讨论】:

      • 还有一个 private 构造函数。
      • 枚举构造函数默认是私有的,不需要访问修饰符。但总的来说,这是关于访问修饰符的一个好点,我已经更新了我的代码以将它们添加到属性和访问器中。
      【解决方案5】:

      如果您想要使用构造函数,并且想要为方法设置一个特殊名称,请尝试以下操作:

      public enum MyType {
        ONE {
            public String getDescription() {
                return "this is one";
            }
        },    
        TWO {
            public String getDescription() {
                return "this is two";
            }
        };
      
        public abstract String getDescription();
      }
      

      我怀疑这是最快的解决方案。没有必要使用variables final

      【讨论】:

      • 但是有了这个,你仍然需要调用 getDescription() ,请求者想要调用 ONE 或将其作为常量访问。
      • 我更喜欢这个。如果它需要接受更多信息会怎样?使用此解决方案,只需添加受保护的抽象方法并覆盖它。更何况不需要重写 toString() 方法。它很干净,可以作为最佳答案接受。
      【解决方案6】:

      枚举的自定义字符串值

      来自http://javahowto.blogspot.com/2006/10/custom-string-values-for-enum.html

      java 枚举的默认字符串值是它的面值,或元素名称。但是,您可以通过覆盖 toString() 方法来自定义字符串值。例如,

      public enum MyType {
        ONE {
            public String toString() {
                return "this is one";
            }
        },
      
        TWO {
            public String toString() {
                return "this is two";
            }
        }
      }
      

      运行以下测试代码会产生这样的结果:

      public class EnumTest {
        public static void main(String[] args) {
            System.out.println(MyType.ONE);
            System.out.println(MyType.TWO);
        }
      }
      
      
      this is one
      this is two
      

      【讨论】:

      • 不是一种有效的方法。这将为枚举中的每个值创建一个新的自定义类。在上面的示例中,您将在bin 目录中看到以下内容: EnumTest$MyType.class EnumTest$MyType$1.class EnumTest$MyType$2.class 将快速添加 real。最好通过将值传递给枚举构造函数来作为预期的答案。我实际上不同意覆盖toString();我认为最好使用明确的 getter,例如 getKey(),因为覆盖 toString() 可能会出乎枚举的其他用户的意料之外。
      • 完全同意@MattQuigley。这样做会鼓励用户将 toString 用于不应该用于的事情。如果你需要一个标签,你宁愿添加一个标签属性
      • 另外,没有办法反过来(从字符串到枚举对象),这可能在某些时候需要。
      • 覆盖 toString 不会影响 valueOf(),是吗?
      • 这可能效率不高,但它肯定是大多数程序员不知道的语言能力。
      【解决方案7】:

      根据您所说的“将它们用作字符串”的含义,您可能不想在这里使用枚举。在大多数情况下,精英绅士提出的解决方案将允许您通过他们的 toString 方法使用它们,例如在System.out.println(STRING_ONE)String s = "Hello "+STRING_TWO 中,但当你真的需要字符串时(例如STRING_ONE.toLowerCase()),你可能更喜欢将它们定义为常量:

      public interface Strings{
        public static final String STRING_ONE = "ONE";
        public static final String STRING_TWO = "TWO";      
      }
      

      【讨论】:

      • 其实这是我想要避免的...!
      • 其实,如果他们也想要我的解决方案上的toLowerCase(),他们可以去Strings.STRING_TWO.toString().toLowerCase()
      • 当然,但这并不是我解释的那样将它们用作字符串。由于 Rrackham 似乎不需要这样使用,他当然应该使用建议的枚举解决方案。
      • 您不应该使用 interface 代替带有 private 构造函数的 final 类。这是一种不鼓励的做法。
      • @mils,使用枚举的解决方案在交换机中同样有效。仅当直接需要字符串时,我才会建议此解决方案。
      【解决方案8】:

      使用它的name() 方法:

      public class Main {
          public static void main(String[] args) throws Exception {
              System.out.println(Strings.ONE.name());
          }
      }
      
      enum Strings {
          ONE, TWO, THREE
      }
      

      产生ONE

      【讨论】:

      • 是的,但是Strings.STRING_ONE.name() 产生“STRING_ONE”,而不是“ONE”。这根本不是一个好的答案。您不能拥有任何不是有效 Java 标识符等的字符串。
      • @Mark,是的,它不能处理任何字符。如果 OP 只想要一个字符,则此解决方案比 The Elite Gentleman 建议更直接。但实际上:如果字符范围超出了有效 Java 标识符可以具有的字符范围,那么这是不行的。好点子。
      • 对于一个与使用 toString() 显示的枚举不同的内部命名约定是非常合理的(特别是如果用户看到输出),所以我不认为这正是 OP 所寻找的。​​span>
      • name() 的结果可能会受到混淆器程序的影响。不久前我遇到了类似的问题。例如,使用 Proguard,您需要解决这个问题。见Processing Enumeration Classes
      • 这太棒了。适用于以下值:var_name、var_superlong_but_not_toooooo_long_name 甚至等(没有三点)
      猜你喜欢
      • 1970-01-01
      • 2023-01-18
      • 2012-10-21
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多