断点调试(debug)

一个实际需求

  1. 在开发中, 新手程序员在查找错误时, 这时老程序员就会温馨提示, 可以用断点调试,一步一步的看源码执行的过程,从而发现错误所在。
  2. 重要提示运行类型 来执行的

 

断点调试介绍

  1. 断点调试是指在程序的某一行设置一个断点, 调试时,程序运行到这一行就会停住, 然后可以一步一步往下调试调试过程中可以看各个变量当前的值,出错的话 , 调试到出错的代码行即显示错误 ,停下 .进而分析从而找到这个BUG
  2. 断点调试是程序员必须掌握的技能。
  3. 断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的Java水平。

断点调试的快捷健:

F7(跳入) F8(跳过) shift + F8(跳出) F9(resume ,执行到下一个断点)

F7 : 跳入方法内

F8 : 逐行执行代码

shift + F8 :跳出方法

断点调试应用案例

 

java的断点调试工具 java debug 断点 原理_java

 鼠标左击行的内容即可以在指定的位置下断点

java的断点调试工具 java debug 断点 原理_断点调试_02

 

 右键选择debug

java的断点调试工具 java debug 断点 原理_断点调试_03

案例 1

 com.edu.debug_ 包 Debug01.java

看一下变量的变化情况等

package com.edu.debug_;

public class Debug01 {
    public static void main(String[] args) {
        //演示逐行执行
        int sum = 0;
        for (int i = 0; i < 5; i++) {
            sum =+ i;
            System.out.println("sum="+sum);
        }
        System.out.println("退出了for循环");
    }
}

设置好断点之后 ,右键debug执行 之后 ,通过点击step over 可以实现逐行执行

当我们查看别人的代码 ,如果看不懂 ,可以通过debug的方法逐行执行 F8

案例 2

Debug02.java

package com.edu.debug_;

public class Debug02 {
    public static void main(String[] args) {
        int[] arr = {1, 10, -1};
        for (int i = 0; i <= arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("退出 for");
    }
}

 

java的断点调试工具 java debug 断点 原理_java_04

 

 

通过debug的调试可以清楚的看到变量的值通过循环逐行执行不断地变化

java的断点调试工具 java debug 断点 原理_java_05

 

 同时我们还可以将鼠标指针放到变量上面点击加号 ,查看变量的详细信息

java的断点调试工具 java debug 断点 原理_断点调试_06

 

 

java的断点调试工具 java debug 断点 原理_断点调试_07

 

当代码执行到这里可以看到出现了错误 : 发现了一个无效的数组范围

再次执行报错了 ,因此我们就可以发现原因是出现了超出了范围的错误

 

案例 3

演示如何追源码,看看 java 设计者是怎么实现的。(提高编程思想)。

小技巧:将光标放在某个变量上,可以看到最新的数据。 Debug03.java

package com.edu.debug_;
import java.util.Arrays;

public class Debug03 {
    public static void main(String[] args) {
        int[] arr = {1, -1, 10, -20, 100};
        //我们看看 Arrays.sort 方法底层实现.->Debug
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }

    }
}

 

java的断点调试工具 java debug 断点 原理_java_08

 

 如果想要进入sort方法中可以输入快捷键F

 

java的断点调试工具 java debug 断点 原理_断点调试_09

 

 可以发现不但数组被排序完成 ,而且在上方的数组右边可以看到发生变化的数组元素 ,以一种特别的颜色注释显示了出来

而为什么F7没有进入这个方法 ,这个时候我们可以通过 force step into 或者 快捷键 alt+shift+F7

java的断点调试工具 java debug 断点 原理_断点调试_10

 

java的断点调试工具 java debug 断点 原理_System_11

 

 可以看到成功进入到了目标的源码中去了

 另外一种解决方法就是通过配置的方式进行解决 

点击 Setting - > Build ,Execution ,Deployment -> Debugger -> Stepping 

将Do not step into the classes 中的java.* ,javax.* 取消勾选 , 其他的随意即可

java的断点调试工具 java debug 断点 原理_java_12

 

 接下来F7就可以成功进入其源码了

也就是说 默认情况下是不让我们进入类中去的 ,因此我们需要自己去配置

此时进入到新的方法当中我们仍然还可以通过F7来继续深入到其中的方法中去

java的断点调试工具 java debug 断点 原理_断点调试_13

 

从这里进入之后

java的断点调试工具 java debug 断点 原理_断点调试_14

 

 可以看到内部的代码量十分之多 ,同时这是一个双组快排的算法

 而此时光标定位到了这个代码当中去之后 ,如果我们想要回到原来的主方法的时候 ,就可以一层层的再跳转回去

即 shift+F8跳出方法

 

java的断点调试工具 java debug 断点 原理_System_15

 

 或者点击这里的step out

java的断点调试工具 java debug 断点 原理_java的断点调试工具_16

 

 当我们跳转回去的时候 ,可以看到sort方法已经执行完毕了 ,同时也可以继续逐行执行

这个过程有点类似递归

 

案例 4

演示如何直接执行到下一个断点 F9 resume。

小技巧: 断点可以在 debug 过程中,动态的下断点

package com.edu.debug_;
import java.util.Arrays;

//演示执行到下一个断点,同时支持动态的下断点.
public class Debug04 {
    public static void main(String[] args) {
        int[] arr = {1, -1, 10, -20, 100};
        //我们看看 Arrays.sort 方法底层实现.->Debug
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println("hello100");
        System.out.println("hello200");
        System.out.println("hello300");
        System.out.println("hello400");
        System.out.println("hello500");
        System.out.println("hello600");
        System.out.println("hello700");
    }
}

 

java的断点调试工具 java debug 断点 原理_System_17

 

 在程序执行之前下两个断点

我们如果不想看中间执行的过程 直接看下一个断点的执行内容 就可以点击F9

java的断点调试工具 java debug 断点 原理_java_18

 

 也就是这个位置

java的断点调试工具 java debug 断点 原理_java的断点调试工具_19

 

可以看到代码不仅跳转到了下一个断点 ,同时也将中间的循环数组也执行完毕了 

而如果我们想要直接执行到hello600的位置 ,那也是可以的 ,只需要在那一行代码上面下一个断点即可

java的断点调试工具 java debug 断点 原理_java_20

 

 同时我们不仅可以给自己写的代码添加断点 ,同时也可以给系统的JDK源码下断点

java的断点调试工具 java debug 断点 原理_System_21

 

 进入到系统的双轴快排源码中去

java的断点调试工具 java debug 断点 原理_System_22

 

 这里通过下断点 ,直接跳转到了这一行的代码中去

这种技巧对以后的多线程开发是十分有用的 ,查看代码对应的业务逻辑就可以使用这个debug调试方法

 

断点调试练习

DebugExercise.java

  1. 使用断点调试的方法 ,追踪下一个对象的创建过程 ,Person[name,age,构造器...]
  2. 我们使用断点调试 ,查看动态绑定机制的如何工作
package com.edu.debug_;

//debug对象创建的过程,加深对调试的理解
public class DebugExercise {
    public static void main(String[] args) {
        //创建对象的流程
        //1.加载Person类信息
        //2.初始化 默认属性初始化 ,显式初始化 ,构造器初始化
        //3.返回对象的地址
        Person jack = new Person("jack",20);
        System.out.println(jack);
    }
}
class Person{
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 首先通过调试可以得出第一步加载类信息

java的断点调试工具 java debug 断点 原理_java_23

 进入到了类加载器中

 即加载这个类

java的断点调试工具 java debug 断点 原理_java的断点调试工具_24

 

 下一步就是进入到构造器中 ,对属性进行初始化操作

java的断点调试工具 java debug 断点 原理_java的断点调试工具_25

 

接下来执行到这个位置的时候 ,会调用到toString方法

 

java的断点调试工具 java debug 断点 原理_System_26

 

 在 String s = String.valueOf(x); 这行调用到toString方法

java的断点调试工具 java debug 断点 原理_断点调试_27

 

obj是否为空 ,否则就调用 toString

 由于obj的运行类型是Person ,因此就会进入到Person的toString方法

java的断点调试工具 java debug 断点 原理_System_28

此时s接收到了toString发过来的字符串

java的断点调试工具 java debug 断点 原理_断点调试_29

 

 到这里信息就输出出来了

java的断点调试工具 java debug 断点 原理_java的断点调试工具_30

 

 

  1. 我们使用断点调试 ,查看动态绑定机制的如何工作

java的断点调试工具 java debug 断点 原理_java的断点调试工具_31

找到我们之前学习多态的时候联系的代码 ,将这个代码

 step into到a.sum()上

java的断点调试工具 java debug 断点 原理_java的断点调试工具_32

 

 此时由于没有找到父类的sum方法 ,因此跳转到子类当中去

 

 

java的断点调试工具 java debug 断点 原理_System_33

 

 

由于a对象的运行类型是B因此当调用getI方法的时候 ,会根据动态绑定机制 ,调用到子类的getI方法中去