4.断点调试
1.IDEA断点调试(Debug)
1.1.为什么需要Debug
编好的程序在执行过程中如果出现错误,该如何查找或定位错误呢?简单的代码直接就可以看出来,但
如果代码比较复杂,就需要借助程序调试来查找错误了。
运行编写好的程序时,可能出现的几种情况: > 情况1:没有任何bug,程序执行正确! ====================如果出现如下的三种情况,都又必要使用debug============================= > 情况2:运行以后,出现了错误或异常信息。但是通过日志文件或控制台,显示了异常信息的位置。 > 情况3:运行以后,得到了结果,但是结果不是我们想要的。 > 情况4:运行以后,得到了结果,结果大概率是我们想要的。但是多次运行的话,可能会出现不是我们想要的情况。 比如:多线程情况下,处理线程安全问题。
1.2.Debug的步骤
Debug(调试)程序步骤如下:
1、添加断点
2、启动调试
3、单步执行
4、观察变量和执行流程,找到并解决问题
添加断点
在源代码文件中,在想要设置断点的代码行的前面的标记行处,单击鼠标左键就可以设置断点,在相同
位置再次单击即可取消断点。

启动调试

单步调试工具介绍




1.3.方法断点
- 断点设置在方法的签名上,默认当进入时,断点可以被唤醒。
- 也可以设置在方法退出时,断点也被唤醒
import java.util.HashMap; public class Debug02 { public static void main(String[] args) { // //1. // Son instance=new Son(); // instance.test(); //2.类的多态性 Father instance1 = new Son(); instance1.test(); //3.接口的多态性 Consumer con=new ConsumerImpl(); con.accept("你好啊"); //4. HashMap map = new HashMap(); map.put("tom",12); map.put("jerry",11); map.put("tony",14); } } class Father{ public void test(){ System.out.println("Father:test1"); System.out.println("Father:test2"); } } class Son extends Father{ @Override public void test(){ System.out.println("Father:test1"); System.out.println("Father:test2"); } } interface Consumer{ void accept(String str); } class ConsumerImpl implements Consumer{ @Override public void accept(String str){ System.out.println("ConsumerImple:"+str); } }

- 在多态的场景下,在父类或接口的方法上打断点,会自动调入到子类或实现类的方法
1.4.字段断点
- 在类的属性声明上打断点,默认对属性的修改操作进行监控

public class Debug02 { 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) { 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 + '}'; } }
1.5.条件断点
public class Debug03 { 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的条件下,执行断点。

1.6.异常断点
- 对异常进行跟踪。如果程序出现指定异常,程序就会执行断点,自动停住。
public class Debug04 { 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()); } }


1.7.线程调
public class Dubug5 { 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(); } }

1.8.强制结束
public class Debug6 { 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("断开连接"); } }

1.9.自定义调试数据试图
public class Debug7 { public static void main(String[] args) { HashMap<Integer,String> map = new HashMap<>(); map.put(1,"高铁"); map.put(2,"网购"); map.put(3,"支付宝"); map.put(4,"共享单车"); System.out.println(map); } }
设置如下;


1.10.常见问题
问题:使用Step Into时,会出现无法进入源码的情况。如何解决?
方案1:使用 force step into 即可
方案2:点击Setting -> Build,Execution,Deployment -> Debugger -> Stepping
把Do not step into the classess中的 java.* 、 javax.* 取消勾选即可。

浙公网安备 33010602011771号