如何在switch中使用null

时间:2012-04-26 11:04:27

标签: java switch-statement

Integer i = ...

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

在上面的代码中,我不能在switch case语句中使用null。我怎么能这样做? 我不能使用default因为那时我想做其他事情。

13 个答案:

答案 0 :(得分:240)

使用Java中的switch语句无法做到这一点。在null

之前检查switch
if (i == null) {
    doSomething0();
} else {
    switch (i) {
    case 1:
        // ...
        break;
    }
}

您不能在switch语句 * 中使用任意对象。编译器不抱怨switch (i) iInteger的原因是因为Java将Integer自动取消装箱到int。正如assylias所说,当NullPointerExceptioni时,拆箱将抛出null

* 从Java 7开始,您可以在String语句中使用switch

Oracle Docs - Switch

中有关switch的更多信息(包括null变量示例)

答案 1 :(得分:75)

switch ((i != null) ? i : DEFAULT_VALUE) {
        //...
}

答案 2 :(得分:32)

如果我是switch(i)

null将抛出NullPointerException,因为它会尝试将Integer取消装入int。所以case null,恰好是非法的,无论如何都永远不会到达。

您需要在switch语句之前检查我是否为空。

答案 3 :(得分:19)

Java文档明确指出:

禁止使用null作为开关标签可以防止编写永远不会执行的代码。如果switch表达式是引用类型(例如盒装基元类型或枚举),则表达式在运行时求值为null时将发生运行时错误。

在执行Swithch语句之前,必须验证null。

if (i == null)

请参阅The Switch Statement

case null: // will never be executed, therefore disallowed.

答案 4 :(得分:12)

假设:

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;
    }
}

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

然而,当我尝试在switch语句中使用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 @ switch(personType) {。我开始实现的一种解决方法(即“解决方案”)是添加UNKNOWN(-1)类型。

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

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

答案 5 :(得分:5)

你必须做一个

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

答案 6 :(得分:4)

有些库试图提供内置java switch语句的替代方法。 Vavr就是其中之一,他们将其概括为模式匹配。

以下是their documentation的示例:

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

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

答案 7 :(得分:0)

你做不到。您可以在switch中使用基元(int,char,short,byte)和String(仅限java 7中的字符串)。原语不能为空。
切换之前,请在单独的条件下检查i

答案 8 :(得分:0)

ServerCertificateCustomValidationCallback

答案 9 :(得分:0)

您还可以使用String.valueOf((Object) nullableString)

switch (String.valueOf((Object) nullableString)) {
case "someCase"
    //...
    break;
...
case "null": // or default:
    //...
        break;
}
  

见有趣的SO Q / A:Why does String.valueOf(null) throw a NullPointerException

答案 10 :(得分:0)

只需考虑SWITCH的工作方式,

  • 如果是原语,我们知道它会因NPE自动装箱而失败
  • 但是对于 String enum ,它可能正在调用equals方法,该方法显然需要在LHS值上调用equals。 因此,鉴于不能在null上调用任何方法,因此 switch 无法处理null。

答案 11 :(得分:0)

基于@tetsuo答案,使用Java 8:

Integer i = ...

switch (Optional.ofNullable(i).orElse(DEFAULT_VALUE)) {
    case DEFAULT_VALUE:
        doDefault();
        break;    
}

答案 12 :(得分:0)

我今天刚刚了解到,您不必仅仅因为检查空值的 if 就再添加一层缩进/大括号。您可以执行以下任一操作:

with open('data.json', 'a') as J:
    # Here -------------^

if (i == null) {
    // ...
} else switch (i) {
    case 1:
        // ...
        break;
    default:
        // ...
}