[英]How do I switch on values defined inside a java enum of strings
I have the following code : 我有以下代码:
class MyClass {
private Value value;
public enum Value {
INSERT_ONLY("INSERT_ONLY"), UPDATE_ONLY("UPDATE_ONLY"), UPSERT("UPSERT") ;
private final String val ;
private Value(final String v) {val = v ;}
public String toString() {return val ;}
public String getVal() {
return val;
}
} ;
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
}
public class one {
public static void main(String[] args) {
MyClass obj = new MyClass() ;
obj.setValue(MyClass.Value.INSERT_ONLY) ;
String s = obj.getValue().toString() ;
String s1 = MyClass.Value.INSERT_ONLY.toString() ;
switch(s) {
case "INSERT_ONLY" : System.out.println("INSERT_ONLY") ;
break ;
case "s2" : System.out.println("s2") ;
break ;
}
}
}
This code works. 此代码有效。 But what I want is that in switch-case I use the strings as defined in the enum Value
. 但是我想要的是在切换情况下,我使用enum Value
定义的字符串。 If I use s1
in case
, it generates an error. 如果在case
使用s1
,它将生成错误。 What is the way out? 出路是什么?
Enums have a method .name()
that returns the enum as a String. 枚举有一个方法.name()
,它以字符串形式返回枚举。 All your "values" are equivalent to this - just switch on that. 您所有的“值”都与此等效-只需打开它即可。
You can delete the value
field, the constructor and getter and call name()
where you are currently calling getValue()
. 您可以删除value
字段,构造函数和getter,并在当前调用getValue()
地方调用name()
getValue()
。
Further, the default implementation of toString()
returns name()
so you can delete your toString()
method without having any effect. 此外, toString()
的默认实现返回name()
因此您可以删除toString()
方法而不会产生任何影响。
Finally, you can switch on the enum itself. 最后,您可以打开枚举本身。
you string in the enum is actually the same as the enumertor constants... so it is a little redundant and completely unnescessary... 您在枚举中的字符串实际上与枚举器常量相同...因此有点多余,完全没有必要...
try this: 尝试这个:
enum Value {
INSERT_ONLY, UPDATE_ONLY, UPSERT;
}
public static void main(String[] args) {
Week obj = new Week() ;
Value s = obj.getValue( ) ;
switch(s) {
case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
break ;
case UPDATE_ONLY : System.out.println("UPDATE_ONLY") ;
break ;
}
}
}
You could try it this way: 您可以这样尝试:
MyClass.Value value = obj.getValue() ;
switch(value) {
case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
break ;
case UPSERT : System.out.println("Upsert") ;
break ;
case UPDATE_ONLY : System.out.println("Update only") ;
break ;
}
Basically, the switch-statement uses the enum-names. 基本上,switch语句使用枚举名称。 So there is no need to apply the toString()
-method on the Value
returned by obj.getValue()
. 因此,无需在obj.getValue()
返回的Value
上应用toString()
方法。
If you would like to know why switch will not work in combination with strings, please have a look here . 如果您想知道为什么switch不能与字符串结合使用,请在此处查看 。 One more suggestion: add also the default-branch to the switch-statement. 另一个建议:在switch语句中也添加default分支。
If I understand correctly, you're trying to look up an enum constant by an unknown string s
. 如果我理解正确,则您正在尝试通过未知字符串s
查找枚举常量。 The reason your case
expression can't be s1
is because it must be a compile-time constant , which s1
is not. 您的case
表达式不能为s1
的原因是,它必须是一个编译时常量 ,而s1
不是。 Since your example seems to be mostly theoretical, I'll suggest a few options and you can pick the most appropriate for your actual case: 由于您的示例似乎主要是理论上的,所以我将建议一些选择,您可以根据实际情况选择最合适的选择:
Assuming the enum names are the same as their value
s (in which case you can scrap the field entirely) and you're just trying to look up an enum by its name, just do this: 假设枚举名称与其value
s相同(在这种情况下,您可以完全废弃该字段),而您只是想按其名称查找枚举,只需执行以下操作:
MyClass.Value v = MyClass.Value.valueOf(s);
This will throw an IllegalArgumentException
if no mapping is found for s1
. 如果未找到s1
映射,则将抛出IllegalArgumentException
。
Still assuming the names are the same, but you do need an actual switch
with some additional cases and custom logic: 仍然假设名称相同,但是您确实需要带有一些其他情况和自定义逻辑的实际switch
:
try { MyClass.Value v = MyClass.Value.valueOf(s); switch (v) { case INSERT_ONLY : System.out.println("INSERT_ONLY") ; break ; } } catch (IllegalArgumentException e) { switch (s) case "s2" : System.out.println("s2") ; break ; } }
If the names are not actually the same, you can add a static map of constants inside the enum class, to simulate valueOf()
: 如果名称实际上不同,则可以在enum类内添加常量的静态映射,以模拟valueOf()
:
public enum Value { ONLY_INSERT("ONLY_INSE"), ONLY_UPDATE("UPDATE_ONLY"), UPSERT("UPSERT") ; private static final Map<String, Value> byName = new HashMap<>(); static { for (Value v : values()) { byName.put(v.getVal(), v); } } public static Value byName(String name) { Value result = byName.get(name); if (result == null) { throw new IllegalArgumentException("Invalid name" + name); } return result; } private final String val ; private Value(final String v) {val = v ;} public String toString() {return val ;} public String getVal() { return val; } } ;
Now you can do the same as the previous solutions, using MyClass.Value.byName()
. 现在,您可以使用MyClass.Value.byName()
与以前的解决方案相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.