Switch能否用String做参数? 参数可以是整数表达式,JDK1.5开始支持Enum类,JDK1.7开始支持String。
对这个感兴趣还有一个原因,是我想在面试中问一下这个问题,如果面试中有类似这样的一个问题的话会非常有趣。验证它其实非常简单,你只需用字符串写一段switch的代码,然后反编译一下,看看编译器是如何翻译它们的就可以了。
这是一个简单的测试程序,它有一个main方法,里面有一个switch块在操作String变量。程序中用到的字符串参数是运行时传递进来的,你可以从main方法的字符串数组中获取到。有三种模式来启动这个程序,主动模式,被动模式,以及安全模式。对于这些已知的确定值,其实用枚举来实现要更好,但如果你已经决定使用字符串了,你得确保你写的是大写的,不要写成小成或者骆驼式的,这样会出现大小写敏感的问题。
- public class StringInSwitchCase {
- public static void main(String[] args) {
- String mode = args[0];
- switch (mode) {
- case "ACTIVE":
- System.out.println("Application is running on Active mode");
- break;
- case "PASSIVE":
- System.out.println("Application is running on Passive mode");
- break;
- case "SAFE":
- System.out.println("Application is running on Safe mode");
- }
- }
- }
可以发现:进行switch的实际是hash值,然后用equals进行安全检查(因为hash值可能会发生碰撞),所以性能不如枚举。switch支持String其实是一个语法糖,在编译后的字节码文件中都会被还原成原生类型,并在相应位置插入了强制转换代码,底层的JVM在switch上并没有修改。
当传入switch的是null时,在运行时对一个null调用hashCode()方法,会抛出NullPointerException;如果case写的是null,那么在编译时无法求出hashcode,就会编译报错。
- import java.io.PrintStream;
- public class StringInSwitchCase{
- public StringInSwitchCase() { }
- public static void main(string args[]) {
- String mode = args[0];
- String s; switch ((s = mode).hashCode()) {
- default: break;
- case -74056953:
- if (s.equals("PASSIVE")) {
- System.out.println("Application is running on Passive mode");
- }
- break;
- case 2537357:
- if (s.equals("SAFE")) {
- System.out.println("Application is running on Safe mode");
- }
- break;
- case 1925346054:
- if (s.equals("ACTIVE")) {
- System.out.println("Application is running on Active mode");
- }
- break;
- }
- }
- }
看到这个代码,你知道原来字符串的switch是通过equals和hashCode()方法来实现的。
记住,switch中只能使用整型,比如byte。short,char以及int。还好hashCode()方法返回的是int,而不是long。
通过这个很容易记住hashCode返回的是int这个事实,事实上我自己都会经常忘了或者弄混。仔细看下可以发现,进行
switch的实际是哈希值,然后通过使用equals方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。
注意:
1.整数表达式可以是int和Integer,而byte、short、char等可以转换成int,所以也可以用。但是long和String不能转换成int,所以不能用
2.String时不能传入null作为参数,同时case语句中使用的字符串也不能为null,因为底层是通过equals和hashmap来判断的
小伙伴们可以关注我的公众号,留言必回复哦
Java核心基础
----------------------------------
长按关注哦(看那两撇小胡子)
基础 | 心得 | 经历 | 更重要的是开心嘛!