【问题标题】:Using Integer in Switch Statement在 Switch 语句中使用整数
【发布时间】:2012-09-26 14:19:16
【问题描述】:

出于各种业务原因,我想在我的一个类中保存一些静态 ID。它们最初是int,但我想将它们更改为Integer,这样我就可以对它们做一个equals(即MY_ID.equals(..),它避免了NPE)

当我将它们更改为整数时,我的 switch 语句中出现错误。 docs 说整数在 Switch 中应该没问题。

引用

[Switch] 也适用于枚举类型(在枚举类型中讨论), String 类,以及一些包装某些特定类的特殊类 原始类型:Character、Byte、Short 和 Integer(在 数字和字符串)。

在我下面的代码中,如果 i 是 int,那么它会编译。当它是Integer 时,它不会说是constant expression is required。我尝试过.intValue(),但这也不起作用。

我真的很傻吗?还是完全误读了docs

private static final Integer i = 1;

@Test
public void test() {
    switch(mObj.getId()){
        case i: //do something
        default: //do something default
    }

}

感谢您在此提供的任何指示。暂时我将它们保留为int 并做new Integer(myint).equals(...)

【问题讨论】:

  • 我建议你使用枚举。它们非常适合这种情况。
  • 是的,我同意@dystroy。这些 ID 与数据库中的 id 匹配,这就是我们使用它的原因。我想我们可以使用枚举...
  • 我也是用DB中匹配的枚举,没有问题。枚举现在在 java 中真的很强大。
  • 我只想澄清原始类型,如 int,不能在 Java 中抛出空指针异常 (NPE),只有对象引用可以。所以使用 int 应该仍然是一个可行的选择。

标签: java switch-statement


【解决方案1】:

将常量更改为原始类型:

private static final int i = 1;

你会没事的。 switch 只能使用原语、枚举值和(从 Java 7 开始)字符串。小贴士:

  • new Integer(myint).equals(...) 可能是多余的。如果至少有一个变量是原始的,只需执行:myint == ...equals() 仅在与 Integer 包装器比较时才需要。

  • 首选Integer.valueOf(myInt) 而不是new Integer(myInt) - 并尽可能依赖自动装箱。

  • 常量在 Java 中通常使用大写,所以static final int I = 1

【讨论】:

  • 准确地说:switch 变量可以是 char、byte、short、integer、enum 和 String(以及对应的 Object)。但case 值必须是常量,即原始类型、枚举值或编译时字符串。
  • 如果你必须像在这段代码中那样使用它怎么办: public class SwitchOca { public static void main(String[] args) { final String x = "0";最终字符串 y = new String("0"); switch(x) { case y: System.out.println("error ...");休息; case "2": System.out.println("primitive ...");休息; } } }
【解决方案2】:

现在 java 提供枚举,我们通常这样做:

public enum MyKey {
   i,
   j
}

...

switch(mObj.getId()){
    case i: //do something
    default: //do something default
}

【讨论】:

    【解决方案3】:

    case 语句或枚举常量中切换require constant expressionsA constant expression is:

    表示原始类型值的表达式或不突然完成的字符串

    所以整数不符合条件。在您的情况下,您可以使用 int 或枚举(如果您的 ID 在编译时已知,这将是有意义的)。

    唯一可以使用盒装类型(例如 Integer)的地方是 switch 表达式:

    switch(Integer.valueOf(1)) {
        case 1: //
    }
    

    【讨论】:

    • 引用我的问题中链接的文档It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer (discussed in Numbers and Strings).我误解了它的意思吗?
    • @RNJ 这仅适用于 switch(expression) 中的表达式,不适用于 case 语句。
    • 虽然我发现 Integer 在 case 语句中没有自动装箱为 int 很有趣。我会期待,但我从未尝试过。即使使用编译时间常数, i 也是最终的,因此编译器应该知道它始终为 1,但我想直到运行时才完成自动装箱。 (不和你争论,只是惊讶)
    【解决方案4】:

    因为我在看这个...

    接受的答案是:

    switch 只能使用原语、枚举值和(从 Java 7 开始) 字符串

    然而,

    14.11 The switch Statement

    概述了用于显示的开关的 JavaSE7 文档:

    Expression的类型必须是char、byte、short、int、Character、Byte、 Short、Integer、String 或枚举类型(第 8.9 节)或编译时错误 发生。

    我只是想为未来的冲浪者澄清一下。

    【讨论】:

    • 准确地说:switch 变量可以是 char、byte、short、integer、enum 和 String(以及对应的 Object)。但case 值必须是常量,即原始类型、枚举值或编译时字符串。
    【解决方案5】:

    您必须在 switch 语句中使用常量值。

    switch(mObj.getId()){
        case 5: //do something
        default: //do something default
    }
    

    【讨论】:

      【解决方案6】:

      在显示的代码中,'i' 是一个对象指针,而不是一个常量表达式。

      【讨论】:

      • 对不起,我不想冒犯你或听起来粗鲁。我只是说在 C/C++ 中称为 pointer 的东西在 Java 中称为 reference (排序)。查看12345。这只是 Java 开发人员之间使用的命名约定。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2015-10-27
      相关资源
      最近更新 更多