Java 如何确保switch/case语句具有使用enum等所有选项?
我想用Java创建一个switch/case语句,并确保所有字符串都在该语句中 但是,使用简单字符串(即北、南、东、西)在Java中创建枚举很容易Java 如何确保switch/case语句具有使用enum等所有选项?,java,enums,switch-statement,Java,Enums,Switch Statement,我想用Java创建一个switch/case语句,并确保所有字符串都在该语句中 但是,使用简单字符串(即北、南、东、西)在Java中创建枚举很容易 如何处理带有点和空格的字符串?i、 e.“这是描述”,“com.stackoverflow.ClassName”我认为这个问题的主要问题是,您的IDE告诉您switch语句中缺少枚举值。并询问您是否要添加它们而不是编译器。当然,这并不能确保枚举类的用户必须使用每个值 Joshua Bloch在其有效的Java书籍(第章使用接口模拟可扩展枚举)中提到了
如何处理带有点和空格的字符串?i、 e.“这是描述”,“com.stackoverflow.ClassName”我认为这个问题的主要问题是,您的IDE告诉您switch语句中缺少枚举值。并询问您是否要添加它们而不是编译器。当然,这并不能确保枚举类的用户必须使用每个值 Joshua Bloch在其有效的Java书籍(第章<代码>使用接口<代码>模拟可扩展枚举)中提到了一种方法,该接口可以更改为与此处显示的交换机一起使用:。但我认为交换机解决方案不能提供使用所有枚举的完全安全性 但是,既然您想知道是否有使用字符串的解决方案,我们也可以尝试使用如下所示的函数式方法:并使其使用字符串字段而不是枚举 这可能如下所示:
public class Direction {
private static final String NORTH = "north";
private static final String SOUTH = "south";
private static final String EAST = "east";
private static final String WEST = "west";
public interface SwitchResult {
void NORTH();
void SOUTH();
void EAST();
void WEST();
}
public static void switchValue(String direction, SwitchResult result){
switch (direction){
case NORTH:
result.NORTH();
break;
case SOUTH:
result.SOUTH();
break;
case EAST:
result.EAST();
break;
case WEST:
result.WEST();
break;
}
}
public static void main(String[] args) {
String direction = "west";
Direction.switchValue(direction, new SwitchResult() {
@Override public void NORTH() {
System.out.println("this time north");
}
@Override public void SOUTH() {
System.out.println("this time south");
}
@Override public void EAST() {
System.out.println("this time east");
}
@Override public void WEST() {
System.out.println("this time west");
}
});
}
}
正如您在main方法中看到的,如果您想调用switchValue函数,您必须传递字符串和接口的实现,这确保您可以覆盖所有可能性。作为交换,代码是非常冗余的。
如果您只有对提供一组字符串值的类的读取权限,并且希望围绕该类构建一个switch语句,则可以使用这种方法。在其他任何地方,您都应该坚持使用枚举的方法
如果您想使用第三方工具真正确保无需编写任何冗余样板代码,请查看:
如果您询问是否可以创建一个
enum
,其中常量有空格,那么答案是“no”
枚举常量是普通的Java标识符,与类或变量名类似,因此它们不能包含空格或特殊字符
但是,是否无法将枚举与字符串链接?否。
如果出于某种原因,您希望您的开关盒使用
enum
以确保可读性/简洁性,但您的输入是字符串,可以有空格,点,特殊字符,那么有一种方法
您需要扩展枚举
,以便有一个额外的字段(我们称之为标签)来保存此字符串
在使用enum
的开关案例的方法中,可以调用findByLabel
方法
返回与提供的字符串
对应的枚举
下面是一个使用enum
值NORTH、EAST、SOUTH、WEST的小示例类
链接到不同(无效枚举命名)结构的字符串
public class EnumExample {
enum SwitchEnum {
NORTH ("North star"),
EAST ("Eastpack rulez!"),
SOUTH ("https://www.southafrica.net/"),
WEST ("java.awt.BorderLayout.WEST");
private final String label;
SwitchEnum(final String label) {
this.label = label;
}
@Override
public String toString() {
return this.label;
}
private static final Map<String,SwitchEnum> map;
static {
map = new HashMap<String,SwitchEnum>();
for (SwitchEnum v : SwitchEnum.values()) {
map.put(v.label, v);
}
}
public static SwitchEnum findByLabel(String label) {
return map.get(label);
}
}
public static String doEnumSwitch(String enumString) {
SwitchEnum enm = SwitchEnum.findByLabel(enumString);
if (enm != null) {
String enumReturn = enm.name() +" : "+ enm;
switch (enm) {
case NORTH:
return enumReturn +" - Up there.";
case EAST:
return enumReturn +" - Now for sale.";
case SOUTH:
return enumReturn +" - Now with 50% more elephants.";
default:
return "UNHANDLED ENUM : "+ enm.name() +" - "+ enm;
}
} else {
return "UNKNOWN ENUM : "+ enumString;
}
}
public static void main(String[] args) {
System.out.println(doEnumSwitch("North star"));
System.out.println(doEnumSwitch("Eastpack rulez!"));
System.out.println(doEnumSwitch("https://www.southafrica.net/"));
System.out.println(doEnumSwitch("java.awt.BorderLayout.WEST"));
System.out.println(doEnumSwitch("I only want to get out of here."));
}
}
公共类枚举示例{
枚举开关枚举{
北方(“北极星”),
东(“东包规则!”),
南部(”https://www.southafrica.net/"),
WEST(“java.awt.BorderLayout.WEST”);
私有最终字符串标签;
SwitchEnum(最终字符串标签){
this.label=标签;
}
@凌驾
公共字符串toString(){
返回此.label;
}
私有静态最终地图;
静止的{
map=新的HashMap();
对于(SwitchEnum v:SwitchEnum.values()){
地图放置(v.标签,v);
}
}
公共静态开关枚举findByLabel(字符串标签){
返回map.get(标签);
}
}
公共静态字符串doEnumSwitch(字符串enumString){
SwitchEnm enm=SwitchEnum.findByLabel(enumString);
如果(enm!=null){
字符串enumReturn=enm.name()+“:”+enm;
开关(enm){
案例北:
return枚举return+“-在上面。”;
案例东:
return枚举return+“-现在出售。”;
南方案例:
return enumReturn+“-现在大象多了50%。”;
违约:
返回“未处理的枚举:”+enm.name()+“-”+enm;
}
}否则{
返回“未知枚举:”+enumString;
}
}
公共静态void main(字符串[]args){
System.out.println(doEnumSwitch(“北极星”);
System.out.println(doEnumSwitch(“Eastpack rulez!”);
System.out.println(doEnumSwitch(“https://www.southafrica.net/"));
System.out.println(doEnumSwitch(“java.awt.BorderLayout.WEST”);
System.out.println(doEnumSwitch(“我只想离开这里”);
}
}
这将产生以下结果
北方:北极星-在那里。
东:东包规则!-现在出售。
南部:-现在大象多了50%。
未处理的枚举:WEST-java.awt.BorderLayout.WEST
未知枚举:我只想离开这里
恐怕你的问题不清楚。你所说的“确保所有字符串都在语句中”是什么意思。那些字符串是什么?通过将它们添加到事例列表中,Java编译器不知道“NORTH”是一组基本方向的一部分。怎么做呢?通过使用枚举。它们正在做你想要做的事情。@kumesana警告,是的,毫无疑问像sonar这样的库也会注意到它。不幸的是,这并不能保证所有的案例都得到处理,它只会告诉你一些没有得到处理。至于默认设置:就个人而言,我尝试毕竟:如果我想让它们得到相同的对待,我不需要不同的值。这里的危险在于