Integer i = ...
    
switch (i) {
    case null:
        doSomething0();
        break;    
}

在上面的代码中,我不能在switch case语句中使用null。我该怎么做呢?我不能用默认,因为我想做别的。


当前回答

你不能。你可以在switch中使用基本类型(int, char, short, byte)和String(仅在java 7中使用字符串)。原语不能为空。 开关前检查i是否处于单独状态。

其他回答

switch (String.valueOf(value)){
    case "null":
    default: 
}

考虑到:

public enum PersonType {
    COOL_GUY(1),
    JERK(2);

    private final int typeId;
    private PersonType(int typeId) {
        this.typeId = typeId;
    }

    public final int getTypeId() {
        return typeId;
    }

    public static PersonType findByTypeId(int typeId) {
        for (PersonType type : values()) {
            if (type.typeId == typeId) {
                return type;
            }
        }
        return null;
    }
}

对我来说,这通常与数据库中的查找表(仅针对很少更新的表)保持一致。

然而,当我试图使用findByTypeId在一个开关语句(从,很可能,用户输入)…

int userInput = 3;
PersonType personType = PersonType.findByTypeId(userInput);
switch(personType) {
case COOL_GUY:
    // Do things only a cool guy would do.
    break;
case JERK:
    // Push back. Don't enable him.
    break;
default:
    // I don't know or care what to do with this mess.
}

…正如其他人所述,这将导致NPE @交换机(personType){。我开始实现的一个变通方法(即“解决方案”)是添加一个UNKNOWN(-1)类型。

public enum PersonType {
    UNKNOWN(-1),
    COOL_GUY(1),
    JERK(2);
    ...
    public static PersonType findByTypeId(int id) {
        ...
        return UNKNOWN;
    }
}

现在,您不必在重要的地方进行空检查,并且可以选择是否处理UNKNOWN类型。(注意:-1在业务场景中不太可能是标识符,但显然要选择对您的用例有意义的标识符)。

一些库尝试提供内置java switch语句的替代方案。Vavr就是其中之一,他们把它推广到模式匹配。

以下是他们文档中的一个例子:

String s = Match(i).of(
    Case($(1), "one"),
    Case($(2), "two"),
    Case($(), "?")
);

您可以使用任何谓词,但它们提供了许多开箱即用的谓词,$(null)是完全合法的。我发现这是一个比替代方案更优雅的解决方案,但这需要java8和对vavr库的依赖…

你必须做出一个

if (i == null) {
   doSomething0();
} else {
   switch (i) {
   }
}

你不能。你可以在switch中使用基本类型(int, char, short, byte)和String(仅在java 7中使用字符串)。原语不能为空。 开关前检查i是否处于单独状态。