使用枚举值作为字符串文字

Lar*_*rry 365 java string enums

使用存储在Enum中的值作为字符串文字的最佳方法是什么?例如:

public enum Modes {
    some-really-long-string,
    mode1,
    mode2,
    mode3
}
Run Code Online (Sandbox Code Playgroud)

然后我可以用它Mode.mode1来返回它的字符串表示mode1.无需继续通话Mode.mode1.toString().

Mic*_*Lee 618

你不能.我想你在这里有四个选择.这四种方案都提供了解决方案,但方法略有不同......

选项一: name()枚举上使用内置.如果您不需要任何特殊的命名格式,这非常好.

    String name = Modes.mode1.name(); // Returns the name of this enum constant, exactly as declared in its enum declaration.
Run Code Online (Sandbox Code Playgroud)

选项二: 如果您想要更多控制,请为您的枚举添加覆盖属性

public enum Modes {
    mode1 ("Fancy Mode 1"),
    mode2 ("Fancy Mode 2"),
    mode3 ("Fancy Mode 3");

    private final String name;       

    private Modes(String s) {
        name = s;
    }

    public boolean equalsName(String otherName) {
        // (otherName == null) check is not needed because name.equals(null) returns false 
        return name.equals(otherName);
    }

    public String toString() {
       return this.name;
    }
}
Run Code Online (Sandbox Code Playgroud)

选项三: 使用静态决赛而不是枚举:

public final class Modes {

    public static final String MODE_1 = "Fancy Mode 1";
    public static final String MODE_2 = "Fancy Mode 2";
    public static final String MODE_3 = "Fancy Mode 3";

    private Modes() { }
}
Run Code Online (Sandbox Code Playgroud)

选项四: 接口包含public,static和final的每个字段:

public interface Modes {

    String MODE_1 = "Fancy Mode 1";
    String MODE_2 = "Fancy Mode 2";
    String MODE_3 = "Fancy Mode 3";  
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案实际上是错误的:你可以调用`.name()`参见:http://stackoverflow.com/a/6667365/887836 (41认同)
  • JavaDoc:**String java.lang.Enum.name()**返回此枚举常量的名称,与其枚举声明中声明的完全相同.**大多数程序员应优先使用toString方法,因为toString方法可能返回一个更加用户友好的名称.**此方法主要用于在正确性取决于获取确切名称的特殊情况下使用不会因版本而异.返回:此枚举常量的名称 (9认同)
  • 不要使用接口来保存常量:*Effective Java*(第3版)建议"仅使用接口来定义类型"(第22项). (4认同)
  • @ kato2不正确..name()方法由编译器自动创建 (2认同)

Rya*_*art 469

每个枚举都有name()和valueOf(String)方法.前者返回枚举的字符串名称,后者给出名称为字符串的枚举值.这就像你在寻找什么?

String name = Modes.mode1.name();
Modes mode = Modes.valueOf(name);
Run Code Online (Sandbox Code Playgroud)

Enum本身也有一个静态valueOf(Class,String),所以你也可以使用

Modes mode = Enum.valueOf(Modes.class, name);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是答案!使用类似A("A")的东西可能是错误的来源,这是无意义的额外工作! (48认同)
  • @Firzen如果允许字符串值包含空格或连字符,则不会出现这种情况,"some-really-long-string"就是这种情况. (11认同)
  • 很多人比Enum.name()更喜欢属性方法的原因是,基于Enum.name()的逻辑永远受价值名称的支配.如果代码将来每次都发生变化,这可能会变成一个非常重要的问题,因为所有先前的逻辑都将在Enum值集的更改中中断.覆盖和使用toString()方法允许开发人员更好地控制使用中的值,包括重复,无效的变量名称字符等.只是不要忘记也覆盖valueOf(). (2认同)

Ben*_*uer 75

您可以toString()为每个枚举值覆盖该方法.

例:

public enum Country {

  DE {
    @Override
    public String toString() {
      return "Germany";
    }
  },
  IT {
    @Override
    public String toString() {
      return "Italy";
    }
  },
  US {
    @Override
    public String toString() {
      return "United States";
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

用法:

public static void main(String[] args) {
  System.out.println(Country.DE); // Germany
  System.out.println(Country.IT); // Italy
  System.out.println(Country.US); // United States
}
Run Code Online (Sandbox Code Playgroud)

  • 丑陋而不可重复使用.提供字符串值作为Country的构造函数然后覆盖枚举的toString()方法要好得多. (7认同)
  • 当你有一个很大的枚举并且只想覆盖一个或两个成员的打印内容时,这是一个很好的技术. (4认同)
  • 这根本不可扩展.不要这样做. (3认同)
  • 我喜欢这个.没有理由不将枚举用作具有更多功能的类,例如获取所有值的列表,获取每种类型的字符串等. (2认同)
  • 这对我来说很有意义 (2认同)

ibe*_*dev 32

正如Benny Neugebauer所提到的,你可以覆盖toString().但是,相反,为每个枚举字段覆盖toString,我更喜欢这样的东西:

public enum Country{
    SPAIN("España"),
    ITALY("Italia"),
    PORTUGAL("Portugal");


    private String value;

    Country(final String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.getValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以添加静态方法来检索所有字段,打印所有字段等.只需调用getValue以获取与每个枚举项关联的字符串


Sea*_*oyd 27

mode1.name()String.valueOf(mode1).我担心它并没有变得更好

  • 和mode1.toString()? (5认同)

小智 20

public enum Modes {
  MODE1("Mode1"),
  MODE2("Mode2"),
  MODE3("Mode3");

 private String value;
 public String getValue() {
    return value;
   }
 private Modes(String value) {
  this.value = value;
 } 
}
Run Code Online (Sandbox Code Playgroud)

您可以在下面的任何地方拨打电话,以便从枚举中获取值作为字符串.

Modes.MODE1.getvalue();
Run Code Online (Sandbox Code Playgroud)

这将返回"Mode1"作为字符串.


Pet*_*rey 6

您可以使用,Mode.mode1.name()但通常不需要这样做.

Mode mode =
System.out.println("The mode is "+mode);
Run Code Online (Sandbox Code Playgroud)

  • 编号name()是final,并且始终返回枚举声明中声明的枚举名称. (9认同)
  • 值得注意的是,+运算符将在枚举上调用toString(),而不是name().并且可以重写toString()以返回除名称之外的其他内容(即使它不可取) (6认同)

Jak*_*sel 6

据我所知,获得这个名字的唯一方法就是

Mode.mode1.name();
Run Code Online (Sandbox Code Playgroud)

但是,如果你真的需要这种方式,你可以这样做:

public enum Modes {
    mode1 ("Mode1"),
    mode2 ("Mode2"),
    mode3 ("Mode3");

    private String name;       

    private Modes(String s) {
        name = s;
    }
}
Run Code Online (Sandbox Code Playgroud)


Eth*_*han 6

对于我的枚举,我真的不想将它们分配给每个1个字符串.这是我在枚举上实现toString()方法的方法.

enum Animal
{
    DOG, CAT, BIRD;
    public String toString(){
        switch (this) {
            case DOG: return "Dog";
            case CAT: return "Cat";
            case BIRD: return "Bird";
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)


Bud*_*ddy 5

你可以简单地使用:

""+ Modes.mode1
Run Code Online (Sandbox Code Playgroud)


Ren*_*lva 5

我对你的问题的解决方案!

import java.util.HashMap;
import java.util.Map;

public enum MapEnumSample {
    Mustang("One of the fastest cars in the world!"), 
    Mercedes("One of the most beautiful cars in the world!"), 
    Ferrari("Ferrari or Mercedes, which one is the best?");

    private final String description;
    private static Map<String, String> enumMap;

    private MapEnumSample(String description) {
        this.description = description;
    }

    public String getEnumValue() {
        return description;
    }

    public static String getEnumKey(String name) {
        if (enumMap == null) {
            initializeMap();
        }
        return enumMap.get(name);
    }

    private static Map<String, String> initializeMap() {
        enumMap = new HashMap<String, String>();
        for (MapEnumSample access : MapEnumSample.values()) {
            enumMap.put(access.getEnumValue(), access.toString());
        }
        return enumMap;
    }

    public static void main(String[] args) {

        // getting value from Description
        System.out.println(MapEnumSample.getEnumKey("One of the fastest cars in the world!"));

        // getting value from Constant
        System.out.println(MapEnumSample.Mustang.getEnumValue());

        System.out.println(MapEnumSample.getEnumKey("One of the most beautiful cars in the world!"));
        System.out.println(MapEnumSample.Mercedes.getEnumValue());

        // doesnt exist in Enum
        System.out.println("Mustang or Mercedes, which one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Mustang or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
                + MapEnumSample.getEnumKey("Ferrari or Mustang, which one is the best?") + " is the best!.");

        // exists in Enum
        System.out.println("Ferrari or Mercedes, wich one is the best?");
        System.out.println(MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
                + MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") + " is the best!");

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,只是为了帮助像我这样的人,寻找老问题的更客观答案:) (2认同)

小智 5

public enum Environment
{
    PROD("https://prod.domain.com:1088/"),
    SIT("https://sit.domain.com:2019/"),
    CIT("https://cit.domain.com:8080/"),
    DEV("https://dev.domain.com:21323/");

    private String url;

    Environment(String envUrl) {
        this.url = envUrl;
    }

    public String getUrl() {
        return url;
    }
}

String prodUrl = Environment.PROD.getUrl();
Run Code Online (Sandbox Code Playgroud)

它将打印:

https://prod.domain.com:1088/
Run Code Online (Sandbox Code Playgroud)

这种枚举字符串常量的设计适用于大多数情况。