V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  Java

switch case 配合 enum 还会生成一个匿名内部类呢?

  •  
  •   amiwrong123 · 2020-04-05 14:27:48 +08:00 · 2294 次点击
    这是一个创建于 1722 天前的主题,其中的信息可能已经有所发展或是发生改变。
    //: enumerated/TrafficLight.java
    // Enums in switch statements.
    import static net.mindview.util.Print.*;
    
    // Define an enum type:
    enum Signal { GREEN, YELLOW, RED, }
    
    public class TrafficLight {
        Signal color = Signal.RED;
        public void change() {
            switch(color) {
                // Note that you don't have to say Signal.RED
                // in the case statement:
                case RED:    color = Signal.GREEN;
                    break;
                case GREEN:  color = Signal.YELLOW;
                    break;
                case YELLOW: color = Signal.RED;
                    break;
            }
        }
        public String toString() {
            return "The traffic light is " + color;
        }
        public static void main(String[] args) {
            TrafficLight t = new TrafficLight();
            for(int i = 0; i < 7; i++) {
                print(t);
                t.change();
            }
        }
    } 
    

    这是一个来自 java 编程思想的代码,我发现 out 目录还生成了一个 TrafficLight$1.class,意思生成了一个匿名内部类呢,这是因为 switchcase 吗?

    TrafficLight.class 部分汇编如下:

      public void change();
       Code:
          0: getstatic     #4                  // Field TrafficLight$1.$SwitchMap$Signal:[I  这里去得到匿名内部类的静态成员
          3: aload_0
          4: getfield      #3                  // Field color:LSignal;
          7: invokevirtual #5                  // Method Signal.ordinal:()I
         10: iaload
         11: tableswitch   { // 1 to 3
                        1: 36
                        2: 46
                        3: 56
                  default: 63
             }
    
    

    TrafficLight$1.class 部分汇编如下:

    class TrafficLight$1 {
     static final int[] $SwitchMap$Signal;  静态成员是个 int 数组
    
     static {};
       Code:
          0: invokestatic  #1                  // Method Signal.values:()[LSignal;
          3: arraylength
          4: newarray       int
          6: putstatic     #2                  // Field $SwitchMap$Signal:[I  为啥这里只有一个 putstatic,之后又三个 getstatic Field $SwitchMap$Signal:[I 呀?
          9: getstatic     #2                  // Field $SwitchMap$Signal:[I
         12: getstatic     #3                  // Field Signal.RED:LSignal;
         15: invokevirtual #4                  // Method Signal.ordinal:()I
         18: iconst_1
         19: iastore
         20: goto          24
         23: astore_0
         24: getstatic     #2                  // Field $SwitchMap$Signal:[I
         27: getstatic     #6                  // Field Signal.GREEN:LSignal;
         30: invokevirtual #4                  // Method Signal.ordinal:()I
         33: iconst_2
         34: iastore
         35: goto          39
         38: astore_0
         39: getstatic     #2                  // Field $SwitchMap$Signal:[I
         42: getstatic     #7                  // Field Signal.YELLOW:LSignal;
         45: invokevirtual #4                  // Method Signal.ordinal:()I
    
    
    
    3 条回复    2020-04-05 19:03:57 +08:00
    lanterboy
        1
    lanterboy  
       2020-04-05 15:26:46 +08:00
    是的,这个内部类是用来存储枚举的映射表的,它记录了枚举和跳转符号的关系。实际上 case 的还是对应的数值,调用时会经过一次枚举对象到索引的转换
    amiwrong123
        2
    amiwrong123  
    OP
       2020-04-05 16:32:39 +08:00
    @lanterboy
    好吧,但是 java 汇编我看得有点迷。。
    TrafficLight.class 部分汇编里,感觉没有那句 getstatic #4 // Field TrafficLight$1.$SwitchMap$Signal:[I 也一样啊。因为后面调用了 Signal 枚举实例的 ordinal 方法了就返回了一个 int 值了啊,感觉也没没用上那个匿名内部类的静态的 int 数组成员啊。
    alamaya
        3
    alamaya  
       2020-04-05 19:03:57 +08:00
    @amiwrong123
    你看漏了 iaload,这里是取了映射数组下标(枚举的 ordinal )的值进行入栈的,这么做是为了使用 tableswitch
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4916 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 77ms · UTC 03:58 · PVG 11:58 · LAX 19:58 · JFK 22:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.