Java 中的 Switch 对整型、字符型、字符串型的具体实现细节

1,017 阅读4分钟
原文链接: www.sdk.cn

摘要:Java 7中,switch的参数可以是String类型了,这对我们来说是一个很方便的改进。到目前为止switch支持这样几种数据类型:byte short int char String 。但是,作为一个程序员我们不仅要知道他有多么好用,还要知道它是如何实现的,witch对整型的支持是怎么实现的呢?

本站采用[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可,转载请在正文明显处注明原文地址

原文地址:www.hollischuang.com/archives/61

Java 7中,switch的参数可以是String类型了,这对我们来说是一个很方便的改进。到目前为止switch支持这样几种数据类型:byte short int char String 。但是,作为一个程序员我们不仅要知道他有多么好用,还要知道它是如何实现的,witch对整型的支持是怎么实现的呢?对字符型是怎么实现的呢?String类型呢?有一点Java开发经验的人这个时候都会猜测switch对String的支持是使用equals()方法和hashcode()方法。那么到底是不是这两个方法呢?接下来我们就看一下,switch到底是如何实现的。

一、switch对整型支持的实现

下面是一段很简单的Java代码,定义一个int型变量a,然后使用switch语句进行判断。执行这段代码输出内容为5,那么我们将下面这段代码反编译,看看他到底是怎么实现的。

publicclass switchDemoInt {publicstaticvoid main(String[] args){int a =5;switch(a){case1:System.out.println(1);break;case5:System.out.println(5);break;default:break;}}}//output 5

反编译后的代码如下:

publicclass switchDemoInt
{public switchDemoInt(){}publicstaticvoid main(String args[]){int a =5;switch(a){case1:// '\001'System.out.println(1);break;case5:// '\005'System.out.println(5);break;}}}

我们发现,反编译后的代码和之前的代码比较除了多了两行注释以外没有任何区别,那么我们就知道,switch对int的判断是直接比较整数的值

二、switch对字符型支持的实现

直接上代码:

publicclass switchDemoInt {publicstaticvoid main(String[] args){char a ='b';switch(a){case'a':System.out.println('a');break;case'b':System.out.println('b');break;default:break;}}}

编译后的代码如下: `public class switchDemoChar

publicclass switchDemoChar
{public switchDemoChar(){}publicstaticvoid main(String args[]){char a ='b';switch(a){case97:// 'a'System.out.println('a');break;case98:// 'b'System.out.println('b');break;}}}

通过以上的代码作比较我们发现:对char类型进行比较的时候,实际上比较的是ascii码,编译器会把char型变量转换成对应的int型变量

三、switch对字符串支持的实现

还是先上代码:

publicclass switchDemoString {publicstaticvoid main(String[] args){String str ="world";switch(str){case"hello":System.out.println("hello");break;case"world":System.out.println("world");break;default:break;}}}

对代码进行反编译:

publicclass switchDemoString
{public switchDemoString(){}publicstaticvoid main(String args[]){String str ="world";String s;switch((s = str).hashCode()){default:break;case99162322:if(s.equals("hello"))System.out.println("hello");break;case113318802:if(s.equals("world"))System.out.println("world");break;}}}

看到这个代码,你知道原来字符串的switch是通过equals()hashCode()方法来实现的。记住,switch中只能使用整型,比如byteshortchar(ackii码是整型)以及int。还好hashCode()方法返回的是int,而不是long。通过这个很容易记住hashCode返回的是int这个事实。仔细看下可以发现,进行switch的实际是哈希值,然后通过使用equals方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。因此它的性能是不如使用枚举进行switch或者使用纯整数常量,但这也不是很差。因为Java编译器只增加了一个equals方法,如果你比较的是字符串字面量的话会非常快,比如”abc” ==”abc”。如果你把hashCode()方法的调用也考虑进来了,那么还会再多一次的调用开销,因为字符串一旦创建了,它就会把哈希值缓存起来。因此如果这个siwtch语句是用在一个循环里的,比如逐项处理某个值,或者游戏引擎循环地渲染屏幕,这里hashCode()方法的调用开销其实不会很大。

好,以上就是关于switch对整型、字符型、和字符串型的支持的实现方式,总结一下我们可以发现,其实swich只支持一种数据类型,那就是整型,其他数据类型都是转换成整型之后在使用switch的。