`

Java7中的switch支持String的实现细节

阅读更多

在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的String支持也终于被加上了。

例如,下面是一段switch中使用String的示例代码。

01
public class Test {
02

03
    public void test(String str) {
04
        switch(str) {
05
        case "abc":
06
            System.out.println("abc");
07
            break;
08
        case "def":
09
            System.out.println("def");
10
            break;
11
        default:
12
            System.out.println("default");
13
        }
14
    }
15

16
}

在switch语句中,String的比较用的是String.equals,因此大家可以放心的使用。
需要注意的是,传给switch的String变量不能为null,同时switch的case子句中使用的字符串也不能为null。
为什么要有这些非null的限制呢?其实,我们只要将这段代码反汇编出来,看一下底层到底是如何实现的,就可以明白了。下面是汇编出来的代码。

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:     aload_0
   1:     invokespecial     #1; //Method java/lang/Object."":()V
   4:     return

public void test(java.lang.String);
  Code:
   0:     aload_1
   1:     astore_2
   2:     iconst_m1
   3:     istore_3
   4:     aload_2
   5:     invokevirtual     #2; //Method java/lang/String.hashCode:()I
   8:     lookupswitch{ //2
          96354: 36;
          99333: 50;
          default: 61 }
   36:     aload_2
   37:     ldc     #3; //String abc
   39:     invokevirtual     #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   42:     ifeq     61
   45:     iconst_0
   46:     istore_3
   47:     goto     61
   50:     aload_2
   51:     ldc     #5; //String def
   53:     invokevirtual     #4; //Method java/lang/String.equals:(Ljava/lang/Object;)Z
   56:     ifeq     61
   59:     iconst_1
   60:     istore_3
   61:     iload_3
   62:     lookupswitch{ //2
          0: 88;
          1: 99;
          default: 110 }
   88:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   91:     ldc     #3; //String abc
   93:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   96:     goto     118
   99:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   102:     ldc     #5; //String def
   104:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   107:     goto     118
   110:     getstatic     #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   113:     ldc     #8; //String default
   115:     invokevirtual     #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   118:     return

}

估计有些同学懒得看这些汇编,其实把上面的汇编代码用Java写出来就是下面的样子了。
写到这里,大家应该能明白为什么不能用null了吧。

01
public class Test {
02
    public void test(String str) {
03
        int i = -1;
04
        switch(str.hashCode()) {
05
        case 96354: // "abc".hashCode()
06
            if (str.equals("abc")) {
07
              i = 0;
08
            }
09
            break;
10
        case 99333: // "def".hashCode()
11
            if (str.equals("def")) {
12
              i = 1;
13
            }
14
            break;
15
        default:
16
            break;
17
        }
18

19
        switch(i) {
20
        case 0:
21
            System.out.println("abc");
22
            break;
23
        case 1:
24
            System.out.println("def");
25
            break;
26
        default:
27
            System.out.println("default");
28
        }
29
    }
30
}

如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。
如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。

switch支持String只是一个语法糖,由javac来负责生成相应的代码。底层的JVM在switch上并没有进行修改。

参考
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
类别: Java
分享到:
评论

相关推荐

    java7 新技术代码示例

    菱形符号()是Java 7中的一个语法糖,简化了泛型实例化的过程。在Java 7之前,我们需要这样创建泛型对象: ```java List<String> list = new ArrayList<String>(); ``` 而在Java 7之后,我们可以使用菱形符号简化为...

    10个Java经典的String面试题!.pdf

    4. **String在switch语句中的使用**:从Java 7开始,`switch`语句可以接受String类型的值,这为编写更灵活的代码提供了便利。 5. **String对象的创建**:`String str = new String("abc");`会创建两个对象。"abc...

    Java领域、switch函数详细解析,代码演示,作业帮助,问答咨询~

    自Java 7起,`switch`语句支持字符串类型的表达式。这大大增强了`switch`语句的功能和灵活性,使其能更广泛地应用于实际开发中。 ##### 3. `switch`表达式的新特性 自Java 14起,`switch`表达式被引入,它可以作为一...

    Java 语法糖详解1

    例如,Java 7中switch语句开始支持字符串(String)和枚举(Enumeration),这是对原有只支持基本类型的一个重大改进。 糖块一:switch支持String与枚举 在Java 7之前,switch仅支持基本数据类型,如int、char等。但...

    Java中String类(字符串操作)的10个常见问题和解决方法

    标题为"Java中String类(字符串操作)的10个常见问题和解决方法"的文档主要探讨了Java语言中字符串处理的核心类String的使用细节和最佳实践。以下是根据文档内容总结的知识点: 1. 字符串比较 在Java中,比较字符串...

    JDK15-java-core-libraries-developer-guide.pdf

    * java.lang:提供了基本的编程接口,包括String、Integer、Long等基本数据类型的实现 * java.util:提供了集合类库,包括ArrayList、LinkedList、HashMap等 * java.io:提供了输入/输出操作的接口,包括文件、网络...

    Java实现复杂的进制转换器功能示例

    Java中还有一些内置的函数来辅助实现进制转换,比如`Integer.toString(int num, int radix)`可以将十进制数转换成任意进制的字符串表示,而`Integer.parseInt(String s, int radix)`则可以将任意进制的字符串转换成...

    Java API SE 7 (English)

    5. **字符串相关改进**:Java 7优化了字符串处理,新增了`String.join()`方法用于连接字符串数组,以及`String.indexOf()`和`String.lastIndexOf()`的变种,支持正则表达式搜索。 6. **菱形运算符**:在创建匿名...

    Java code Java code

    8. **多线程**:Java内置对多线程的支持,通过`Thread`类或实现`Runnable`接口可以创建并运行多个线程。 9. **I/O流**:Java的I/O流用于读写文件、网络通信等,包括字节流和字符流。 10. **泛型**:Java泛型提高了...

    Java JDK 7学习笔记

    下面我们将深入探讨Java JDK 7中的重要知识点。 1. **自动类型推断(Type Inference)**: 通过`钻石操作符<>`,Java 7简化了泛型实例化过程,如`List<String> list = new ArrayList();`,编译器可以自动推断出泛型...

    Java练习题库(含答案及解析).pdf

    Java中的条件语句(如if、switch)和循环语句(如for、while、do...while)用于控制程序的流程。Java中的break语句可以用来跳出当前循环,而continue语句用于跳过当前循环的剩余部分并开始下一次循环。 Java中的...

    JAVA面试题汇总.pdf

    7. Java 中的访问修饰符: - public、protected、default(无修饰符)、private。 8. 接口(Interface)和抽象类(Abstract Class)的访问修饰符: - 接口中的方法默认为 public,变量默认为 public static final...

    java万年历代码.java万年历代码

    根据给定的文件信息,我们可以总结出以下关于Java万年历代码的相关知识点: ### 1. 项目概述 ...此外,程序还考虑到了输入月份的第一天是一周中的哪一天这一细节,使得输出结果更加符合实际情况。

    java代码细节总结1.0版本.7z

    - 变量声明:Java中变量必须先声明后使用,可以指定类型如`int`, `String`等。 - 类型转换:自动类型转换(宽化转换)和强制类型转换(窄化转换)的规则。 - 控制流:`if`, `for`, `while`语句,以及`switch`语句...

    入门学习Java For Beginners: A Simple Start To Java Programming

    字符串处理是Java中的一个重要方面,Java提供了String类来处理字符串数据。字符串的方法包括连接、比较、替换、转换大小写等。数组是用于存储固定大小的同一类型元素的数据结构。Java的数组在声明和初始化后,其大小...

    java面试宝典

    - `switch`语句从Java 7开始支持`String`类型。 **6. shorts1=1;s1=s1+1;有什么错?shorts1=1;s1+=1;有什么错?** 在第一种情况下,`s1=s1+1`会导致编译错误,因为`1`是整型默认值,而`s1`是`short`类型,它们之间不...

Global site tag (gtag.js) - Google Analytics