Debug

0、Debug的步骤

Debug(调试)程序步骤如下:

1、添加断点

2、启动调试

3、单步执行

4、观察变量和执行流程,找到并解决问题

 1、添加断点

        在源代码文件中,在想要设置断点的代码行的前面的标记行处,单击鼠标左键就可以设置断点,在相同位置再次单击即可取消断点。

 2、启动调试

示例代码:
 

public class Debug01 {
    public static void main(String[] args) {
        //1.
        int m = 10;
        int n = 20;
        System.out.println("m = " + m + ",n = " + n);
        swap(m, n);
        System.out.println("m = " + m + ",n = " + n);
        //2.
        int[] arr = new int[] {1,2,3,4,5};
        System.out.println(arr);//地址值

        char[] arr1 = new char[] {'a','b','c'};
        System.out.println(arr1);//abc
    }

    public static void swap(int m, int n) {
        int temp = m;
        m = n;
        n = temp;
    }

}

    启动调试:IDEA提供多种方式来启动程序(Launch)的调试,

              分别是通过菜单(Run –> Debug)、图标(“绿色臭虫”)等等

        如果你还是用Run启动,那就不会出现debug效果,断点跟没有打一样:

         启动调试:方法一

         方法二

        方法三:

 代码会停留在我们第一个打断点的位置:只是走到这个断点的位置,此行代码还没有被执行:

1、 Step Over(F8):

        单步执行,进入下一步,如果当前行断点是调用一个方法,则不进入当前方法体内:


蓝色高亮的那一行是我们即将要执行的语句,不是已经执行完毕的语句

单步执行,如果当前行断点是调用一个方法,则不进入当前方法体内,也就是说你看不到方法内部的执行情况,这里你看不到swap(m,n)的执行情况,此时你要用到:

当我们点击Step into时: 

 再Step into一下:

 跳出此方法:

 如果你现在在main方法中,你点击step out的话,main方法就执行结束了,结束的是当前方法!

Resume Program(F9):恢复程序运行,但如果该断点下面还有断点则停在下一个断点上:

Run to Cursor(Alt + F9):直接跳到光标处继续调试 

多种Debug情况介绍

行断点

断点打在代码所在的行上。执行到此行时,会停下来。我们上面的例子都是行断点

方法断点

        断点设置在方法的签名上,当执行此方法时,断点可以被唤醒,也可以设置在当执行完方法退出时,断点也被唤醒:

进入方法的时候会做一个停留,你也可以设置当执行完方法的时候也做一个停留 

在多态的场景下,在父类或接口的方法上打断点,会自动调入到子类或实现类的方法:

如果我对父类中的方法、接口中的抽象方法进行方法断点呢?

当调用了子类的test方法时:(我们明明没在子类的test方法上打断点,但是也停留了)

同理,直接唤醒到我们接口的实现类方法的位置:

你也可以对源码进行方法断点!

字段断点

在进行修改的时候就会起作用


public class Debug03 {
    public static void main(String[] args) {
        Person p1 = new Person(3);
        System.out.println(p1);
    }
}
class Person{
    private int id = 1;
    private String name;
    private int age;
    public Person() {
    }
    {
        id = 2;
    }
    public Person(int id) {
        this.id = id;
    }
    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

id变量默认值为0,所以赋值为1也算作修改:private int id = 1;

当调用对属性值进行修改的地方就会起作用,读取属性值不起作用:

Debug_第1张图片

Debug_第2张图片

Debug_第3张图片

Debug_第4张图片

Debug_第5张图片

                        这样的话除了前面的三次停留,还会有第四次停留:

Debug_第6张图片

        如果你的程序中发现你的某个字段值并不是你想要的结果,那么你就可以加上字段断点,看看有哪些地方对它进行了修改。 

 条件断点

                        在满足某个条件的情况下,断点就会起作用!

public class Debug04 {
public static void main(String[] args) { 
        int[] arr = new int[]{1,2,3,4,5,6,7,8,9,10,11,12};
        for (int i = 0; i < arr.length; i++) {
             int target = arr[i];
             System.out.println(target);
        }
    }
}

                针对上述代码,在满足arr[i] % 3 == 0的条件下,执行断点:  

Debug_第7张图片

 异常断点

        对异常进行跟踪。如果程序出现指定异常,程序就会执行断点,自动在抛出异常的地方进行暂停

        异常断点是无需在具体的代码上打断点的,而是在断点详情页中直接添加,后续在执行时,如果抛出我们监听的异常,则会自动暂停在抛出异常的地方。

 程序出异常了,在终止之前,这个debug就会起作用

public class Debug05 {
        public static void main(String[] args) {
            int m = 10;
            int n = 0;
            int result = m / n;
            System.out.println(result);
            // Person p1 = new Person(1001); 
            // System.out.println(p1.getName().toUpperCase());
        }
}

Debug_第8张图片

Debug_第9张图片

                                 你现在可以点击➕,来添加一个异常断点:

Debug_第10张图片

Debug_第11张图片

Debug_第12张图片

              以Debug的方式启动程序,此时代码就停留在这里了,因为出现了一个算数异常 

Debug_第13张图片

Debug_第14张图片

你也可以加上其他异常断点,例如空指针异常:

Debug_第15张图片

Debug_第16张图片

线程调试:

          在多线程开发的场景中,当我们只想针对某一个线程进行调试,该怎么办呢?

                                                        针对某一个线程考虑

public class Debug06 {
        public static void main(String[] args) {
              test("Thread1");
              test("Thread2");
}
public static void test(String threadName) { 
          new Thread(
                 () -> {
                   for (int i = 0; i < 100; i++) {
                     System.out.println(Thread.currentThread().getName() + ":" + i);
                   }
                  },
                  threadName
                  ).start();
           }
}

Debug_第17张图片

Debug_第18张图片

        "Thread2".equals(Thread.currentThread().getName()),debug方式启动:

                  你会发现Thread1线程全部打印完了,因为断点只针对Thread2起作用,

                                        Thread1一直运行着直到结束:

Debug_第19张图片

Debug_第20张图片

强制结束:

                        功能:强制结束当前程序运行流程,直接返回。

public class Debug07 {
    
        public static void main(String[] args) {
            System.out.println("获取请求的数据");
            System.out.println("调用写入数据库的方法");
            insert();
            System.out.println("程序结束");
        }
        private static void insert() {
            System.out.println("进入insert()方法");
            System.out.println("获取数据库连接");
            System.out.println("将数据写入数据表中,请三思呀!!");
            System.out.println("写出操作完成");
            System.out.println("断开连接");
        }
}

        当我们调试时,发现继续往下执行就要将错误的数据写入数据库时,我们可以通过 Force Return 来强行结束当前流程:

Debug_第21张图片

Debug_第22张图片

Debug_第23张图片

        而如果我们是通过 Stop 按钮来结束,此时结束的是 Debug 流程,而程序流程还是会往下执行,从而将错误数据写入数据库:

Debug_第24张图片

 

自定义调试数据视图:

public class Debug08 { 
public static void main(String[] args) { 
            HashMap map = new HashMap<>(); 
            map.put(1,"高铁"); 
            map.put(2,"网购"); 
            map.put(3,"支付宝"); 
            map.put(4,"共享单车"); 
            System.out.println(map); 
        } 
}

                默认情况,当我们debug运行时,只能看见key、value,看不见map里面的数组:

Debug_第25张图片

                在执行的过程中,我想看看map里面的数组、属性的情况,那我们就可以自定义视图了,在空白的位置右键:

Debug_第26张图片

Debug_第27张图片

                 把这三个勾选上后:

Debug_第28张图片

 

Debug_第29张图片

Debug_第30张图片

 

你可能感兴趣的:(java,算法,开发语言)