• idea在continue的breakpoint不起作用


    1,背景

    调试代码的时候遇到continue处的breakpoint不起作用,故记录一下过程。

    2,分析过程

    2.1,复现

    public class test {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                if (i ==  5) {
                    System.out.println(i);
                    continue;
                }
            }
        }
    }
    

    image

    程序直接执行完并结束,断点未起作用

    2.2,分析

    check了一下代码的字节码

    // class version 52.0 (52)
    // access flags 0x21
    public class test {
    
      // compiled from: test.java
    
      // access flags 0x1
      public <init>()V
       L0
        LINENUMBER 8 L0
        ALOAD 0
        INVOKESPECIAL java/lang/Object.<init> ()V
        RETURN
       L1
        LOCALVARIABLE this Lcom/test; L0 L1 0
        MAXSTACK = 1
        MAXLOCALS = 1
    
      // access flags 0x9
      public static main([Ljava/lang/String;)V
       L0
        LINENUMBER 11 L0
        ICONST_0
        ISTORE 1
       L1
       FRAME APPEND [I]
        ILOAD 1
        BIPUSH 10
        IF_ICMPGE L2
       L3
        LINENUMBER 12 L3
        ILOAD 1
        ICONST_5
        IF_ICMPNE L4
       L5
        LINENUMBER 13 L5
        GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
        ILOAD 1
        INVOKEVIRTUAL java/io/PrintStream.println (I)V
       L4
        LINENUMBER 11 L4
       FRAME SAME
        IINC 1 1
        GOTO L1
       L2
        LINENUMBER 17 L2
       FRAME CHOP 1
        RETURN
       L6
        LOCALVARIABLE i I L1 L2 1
        LOCALVARIABLE args [Ljava/lang/String; L0 L6 0
        MAXSTACK = 2
        MAXLOCALS = 2
    }
    

    通过字节码发现一个问题,并没有找到LINENUMBER 13,就好像这行代码并没写过一样。难道continue字段消失了?
    将代码稍微调整一下:

    public class test {
    
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                if (i ==  5) {
                    continue;
                } else {
                    System.out.println(i);
                }
            }
        }
    }
    

    image
    可以发现断点生效了,然后check一下字节码:

    // class version 52.0 (52)
    // access flags 0x21
    public class test {
    
      // compiled from: test35.java
    
      // access flags 0x1
      public <init>()V
       L0
        LINENUMBER 8 L0
        ALOAD 0
        INVOKESPECIAL java/lang/Object.<init> ()V
        RETURN
       L1
        LOCALVARIABLE this Ltest; L0 L1 0
        MAXSTACK = 1
        MAXLOCALS = 1
    
      // access flags 0x9
      public static main([Ljava/lang/String;)V
       L0
        LINENUMBER 11 L0
        ICONST_0
        ISTORE 1
       L1
       FRAME APPEND [I]
        ILOAD 1
        BIPUSH 10
        IF_ICMPGE L2
       L3
        LINENUMBER 12 L3
        ILOAD 1
        ICONST_5
        IF_ICMPNE L4
       L5
        LINENUMBER 13 L5
        GOTO L6
       L4
        LINENUMBER 15 L4
       FRAME SAME
        GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
        ILOAD 1
        INVOKEVIRTUAL java/io/PrintStream.println (I)V
       L6
        LINENUMBER 11 L6
       FRAME SAME
        IINC 1 1
        GOTO L1
       L2
        LINENUMBER 18 L2
       FRAME CHOP 1
        RETURN
       L7
        LOCALVARIABLE i I L1 L2 1
        LOCALVARIABLE args [Ljava/lang/String; L0 L7 0
        MAXSTACK = 2
        MAXLOCALS = 2
    }
    

    可以发现 出现了 LINENUMBER 13 L5的内容了。

    所以为什么会有这种差异呢?其实就是javac编译期对代码做了优化,示例中的代码的continue逻辑是可以去掉的,然后javac编译时会做这个优化,因此断点调试时无法断点,并不是因为continue具有特殊性。

    3,结论

    不得不佩服java编译器的强大,在断点gson代码的时候发现断点continue一直未生效,还以为是找错地方了,原来是因为断点打在了可有可无的continue上了。

  • 相关阅读:
    master线程的主循环,后台循环,刷新循环,暂停循环
    InnoDB的后台线程(IO线程,master线程,锁监控线程,错误监控线程)和内存(缓冲池,重做日志缓冲池,额外内存池)
    MySQL的连接方式
    编写高质量的 Java 代码
    TProfiler
    Copy-On-Write容器
    G1 垃圾收集器
    JAVA 虚拟机钩子
    Future和Promise
    算法笔记_134:字符串编辑距离(Java)
  • 原文地址:https://www.cnblogs.com/cord/p/16768716.html
Copyright © 2020-2023  润新知