switch实现比较字符串的原理--姥姥家的程序员

switch实现比较字符串的原理

在java1.7之前大家都清楚switch的比较范围只能局限于(int 、short 、byte 、char)之间,Java 虚拟机和字节代码这个层次上,只支持在 switch 语句中使用与整数类型兼容的类型。在1.7后switch实现字符串比较的功能。具体是如何做到的?实际上,Java虚拟机和字节码层次上只支持switch语句中使用与整数类型兼容的类型没有变,只是这个实现字符串比较的新特性是在编译器这个层次上实现的。实现的机制是:将字符串之间的比较转换为其哈希值的比较。

源代码:

public static void main(String[] args) {
	switch ("sitech") {
	case "paas":
		System.out.println("paas");
		break;
	case "sitech":
		System.out.println("sitech");
		break;
	default:
		break;
	}
}

编译后的代码:


public static void main(String[] args)
  {
    String str;
	    switch ((str = "sitech").hashCode())
	    {
	    case -902089236: 
	      if (str.equals("sitech")) {
	        break;
	      }
	    case 3432931: 
	      if ((goto 78) && (str.equals("paas")))
	      {
	        System.out.println("paas");
	        return;
	        
	        System.out.println("sitech");
	      }
	      break;
	    }
  }

从反编译后的字节码文件中可以看出, 原来用在 switch 语句中的字符串被替换成了对应的哈希值,而 case 子句的值也被换成了原来字符串常量的哈希值。经过这样的转换,Java 虚拟机所看到的仍然是与整数类型兼容的类型。

既然是哈希值得比较了,为什么在 case 子句对应的语句块中仍然保留 String 的 equals 方法来进行字符串比较?这是因为哈希函数在映射的时候可能存在冲突,多个字符串的哈希值可能是一样的。进行字符串比较是为了保证转换之后的代码逻辑与之前完全一样。

你可能感兴趣的:(java,switch,java)