如何在switch中使用null

问题描述 投票:176回答:11
Integer i = ...

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

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

java switch-statement
11个回答
247
投票

使用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

更多关于switch中的Oracle Docs - Switch(包括null变量的示例)


0
投票

你不能。您可以在switch中使用基元(int,char,short,byte)和String(仅限java 7中的字符串)。原语不能为空。 在切换之前在单独的条件下检查Why does String.valueOf(null) throw a NullPointerException


0
投票

只考虑SWITCH如何工作,

  • 在原语的情况下,我们知道它可以通过NPE自动装箱失败
  • 但对于String或enum,它可能正在调用equals方法,这显然需要一个LHS值,在该值上调用equals。因此,如果没有方法可以在null上调用,则switch cant句柄为null。

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

33
投票

如果我是switch(i)null将抛出NullPointerException,因为它会尝试将Integer拆箱到int。所以case null,恰好是非法的,无论如何都永远不会到达。

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


19
投票

Java文档明确指出:

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

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

if (i == null)

The Switch Statement

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

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
投票

你必须做一个

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

4
投票

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

以下是switch的一个例子:

Vavr

你可以使用任何谓词,但它们提供了许多开箱即用的功能,而their documentation完全合法。我发现这是一个比替代品更优雅的解决方案,但这需要java8和vavr库的依赖...


1
投票

你也可以使用String s = Match(i).of( Case($(1), "one"), Case($(2), "two"), Case($(), "?") ); 之类的

$(null)

见有趣的SO Q / A:String.valueOf((Object) nullableString)


1
投票
switch (String.valueOf((Object) nullableString)) {
case "someCase"
    //...
    break;
...
case "null": // or default:
    //...
        break;
}
© www.soinside.com 2019 - 2024. All rights reserved.