欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java Switch对各类型支持实现原理

程序员文章站 2022-05-25 22:05:51
switchjava7开始,switch的参数可以是string类型了,这真的是一个很有用的改进,毕竟string还是挺常用的。到目前为止,switch支持的参数类型有:byte、short、int、...

switch

java7开始,switch的参数可以是string类型了,这真的是一个很有用的改进,毕竟string还是挺常用的。到目前为止,switch支持的参数类型有:byte、short、int、char、string、enum。switch对各种类型参数的支持到底是怎么实现的呢?

byte、short、int

public class main2 {
  public static void main(string[] args) {
    byte b = 1;
    switch (b) {
      case 0:
        system.out.println("0");
        break;
      case 1:
        system.out.println("1");
        break;
      default:
        system.out.println("other");
    }
  }
}

反编译:

public class main2 {
  public main2() {
  }
  public static void main(string[] args) {
    byte b = 1;
    switch(b) {
      case 0:
        system.out.println("0");
        break;
      case 1:
        system.out.println("1");
        break;
      default:
        system.out.println("other");
    }
  }
}

将byte换成short、int,编译后的结果与上面展示的基本相同。

char

public class main2 {
  public static void main(string[] args) {
    char c = '0';
    switch (c) {
      case '0':
        system.out.println("0");
        break;
      case '1':
        system.out.println("1");
        break;
      default:
        system.out.println("other");
    }
  }
}

反编译:

public class main2 {
  public main2() {
  }
  public static void main(string[] args) {
    char c = 48;
    switch(c) {
      case 48:
        system.out.println("0");
        break;
      case 49:
        system.out.println("1");
        break;
      default:
        system.out.println("other");
    }
  }
}

从反编译的结果看,对char类型进行比较的时候,实际比较的是字符对应的ascⅱ码,编译器把switch中char类型的变量转换成int类型的变量。

string

public class main2 {
  public static void main(string[] args) {
    string s = "0";
    switch (s) {
      case "0":
        system.out.println("0");
        break;
      case "1":
        system.out.println("1");
        break;
      default:
        system.out.println("other");
    }
  }
}

反编译:

public class main2 {
  public main2() {
  }

  public static void main(string[] args) {
    string s = "0";
    byte var3 = -1;
    switch(s.hashcode()) {
      case 48:
        if (s.equals("0")) {
          var3 = 0;
        }
        break;
      case 49:
        if (s.equals("1")) {
          var3 = 1;
        }
    }

    switch(var3) {
      case 0:
        system.out.println("0");
        break;
      case 1:
        system.out.println("1");
        break;
      default:
        system.out.println("other");
     }
  }
}

从反编译的结果看,switch借助hashcode()和equals()实现了对string的支持——先使用hashcode进行初步判断,然后使用equal()进行二次校验(由于哈希冲突的存在,这个二次校验是必要的)。

public enum colorenum {
  red, yellow, blue, greed
}
public class main {
  public static void main(string[] args) {
    colorenum color = colorenum.yellow;
    switch (color) {
      case red:
        system.out.println("red");
        break;
      case yellow:
        system.out.println("yellow");
        break;
      default:
        system.out.println("other");
    }
  }
}

反编译:

/*
 * decompiled with cfr 0.149.
 */
package com.learn.java;

public final class colorenum
extends enum<colorenum> {
  public static final /* enum */ colorenum red = new colorenum("red", 0);
  public static final /* enum */ colorenum yellow = new colorenum("yellow", 1);
  public static final /* enum */ colorenum blue = new colorenum("blue", 2);
  public static final /* enum */ colorenum greed = new colorenum("greed", 3);
  private static final /* synthetic */ colorenum[] $values;

  public static colorenum[] values() {
    return (colorenum[])$values.clone();
  }

  public static colorenum valueof(string string) {
    return enum.valueof(colorenum.class, string);
  }

  private colorenum(string string, int n) {
    super(string, n);
  }

  static {
    $values = new colorenum[]{red, yellow, blue, greed};
  }
}
/*
 * decompiled with cfr 0.149.
 */
package com.learn.java;

import com.learn.java.colorenum;

public class main {
  public static void main(string[] arrstring) {
    colorenum colorenum = colorenum.yellow;
    switch (1.$switchmap$com$learn$java$colorenum[colorenum.ordinal()]) {
      case 1: {
        system.out.println("red");
        break;
      }
      case 2: {
        system.out.println("yellow");
        break;
      }
      default: {
        system.out.println("other");
      }
    }
  }
}

上面的反编译结果表明,switch借助枚举类的序号实现对枚举类的支持。

总结

其实switch只支持整型,其他数据类型都是转换成整型后才使用的switch。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。