一、断点调试
1. 源断点
要输出每一次的参数信息:
System.out.print
不应该使用它,它是一个同步方法,是线程安全,过多时会挤占线程、占用资源!
//内部实现
public void println(int x) {
synchronized (this) {
print(x);
newLine();
}
}
shift+鼠标左键,出现黄色标记:
![image-20220323212141714](https://s2.loli.net/2022/03/27/hnFE49VYde1Zx5z.png)
相关的信息:
![image-20220323212619092](https://s2.loli.net/2022/03/27/92g4bM7KmJjrZF8.png)
以debug方式执行就可以输出相应信息
可以打印日志,所在行信息、堆栈信息,只需要点击相应的选框
命中后移除:执行完毕后移除断点
合格次数:行断点时使用
2. 行断点
解析每一步的执行步骤,鼠标左击会出现红色标记
debug执行:
![截屏2022-03-23 21.37.24](https://s2.loli.net/2022/03/27/XFSi6jnEkJtM4PH.png)
控制台打印每一个变量的信息:
指定调试开始处与结束处:
![image-20220323214300244](https://s2.loli.net/2022/03/27/zghqQX8iArUj4V7.png)
![image-20220323214934000](https://s2.loli.net/2022/03/27/uQtUXKhpOjwNJIM.png)
只执行固定方法的断点:
![image-20220323215532524](https://s2.loli.net/2022/03/27/ZjCsg1B5iMAIcLk.png)
3.方法断点
public class ServiceImplA implements Service{
@Override
public String method() {
return "hello A";
}
}
public class ServiceImplB implements Service{
@Override
public String method() {
return "hello B";
}
}
public String hello() { // 假设通过看代码很难确定是哪个实现类的实例
Service service = createService();
return service.method();
}
这个时候,我们不能一眼看出 service 是 ServiceImplA 的实例,还是 ServiceImplB 的实例
4.属性断点
当一个成员变量被多方引用时,它可以精准的找到谁读取、修改了它的值。
![image-20220324162742531](https://s2.loli.net/2022/03/27/iTDugmFekqwxVfr.png)
5.异常断点
可以精准的定位到发生(指定类型)异常的代码行。
此时以debug方式运行会抛出异常:
![image-20220324161921300](https://s2.loli.net/2022/03/27/ytr6kQvR2hMUVBG.png)
但此时加上一个断点,并且添加一个异常类,就能够停在异常断点处:
![image-20220324162056161](https://s2.loli.net/2022/03/27/GsuCmXEODNMlV2j.png)
![image-20220324162214052](https://s2.loli.net/2022/03/27/dXRaDBeW6kZGS7c.png)
6.断点工具栏
![image-20220324170504194](https://s2.loli.net/2022/03/27/rvtOksopbnGhBDN.png)
7.安全退出
退出后不再进行断点之后的执行
开启返回:
8.多线程调试
默认:
勾选Thread:
可以在两个线程间切换调试:
9.远程断点调试
不建议使用
建立远程连接:
打包项目,推送到远程服务器上:
控制台:
进入远程服务器:
项目跑起来了:
![image-20220325180352380](https://s2.loli.net/2022/03/25/qQFGuW52ZrvdHIB.png)
打了断点之后再次在浏览器访问:
二、代码重构
1. 修改名称
shift+f6:修改类名、方法名、包名
2. 更改方法签名
选中方法名后com+f6,修改方法参数:
![image-20220324174345824](https://s2.loli.net/2022/03/27/jONcsw3kR7PLMaz.png)
3. 方法抽取
抽取方法
选中方法后com+option+N:
![image-20220324174604570](https://s2.loli.net/2022/03/27/O9fsm5gvDkEpFVK.png)
(只内联这个并保留这个方法)执行后:
![image-20220324175018474](https://s2.loli.net/2022/03/27/pOmEAHjiKvMoSBn.png)
抽取常量
抽取前
![image-20220324175239858](https://s2.loli.net/2022/03/27/MLFka7YBZbAvJPh.png)
抽取后com+option+C:
![image-20220324175403894](https://s2.loli.net/2022/03/27/a2KsWxmr9i5ZChD.png)
抽取变量
抽取前:
![image-20220324175505846](https://s2.loli.net/2022/03/27/2glVpaOfxtIeq16.png)
抽取后com+shfit+V:
![image-20220324175553678](https://s2.loli.net/2022/03/27/5aFTWhkPrGX6ipe.png)
在此选中上图中蓝色部分,将其抽取为全局变量com+option+F:
![image-20220324175750227](https://s2.loli.net/2022/03/27/pXBoqJ1WRamd9uC.png)
抽取参数
![image-20220324202331076](https://s2.loli.net/2022/03/24/lPanXJ9bsSphqQM.png)
com+option+P:
![image-20220324201350198](https://s2.loli.net/2022/03/24/CIJNxodlsHyVQA7.png)
抽取父类方法到子类,子类到父类
![image-20220324201539282](https://s2.loli.net/2022/03/24/Lsbt8JMTHoSqy4K.png)
抽取方法到接口中
抽取方法到指定类中
以上这些都可以通过idea上方的状态栏重构功能中找到!
三、快捷键操作
1. 自定义模板
${desc}表示要手动输入说明
2. 自定义快捷键模板
![image-20220325155723242](https://s2.loli.net/2022/03/25/RKH4x9rVoSmTNUh.png)
生效后:
![image-20220325155844409](https://s2.loli.net/2022/03/25/lCIonq86xAHufmU.png)
3.常用快捷键
mac系统
-
com+shift+回车
智能补全 -
shift+回车
生成下一行 -
com+option+T
环绕方式 -
com+N
生成代码 -
com+D
向下复制 -
com+/
注释 -
com+'-'
折叠 -
com+'+'
展开 -
com+'.'
折叠/展开 -
ctrl+shift+R
运行 -
ctrl+D
debug运行 -
com+delete
删除当前行 -
command+R
查找和替换 -
shift*2
快速查找
4.使用技巧
优化import语句
![image-20220325163410160](https://s2.loli.net/2022/03/25/FLjHn2S8csCdMQJ.png)
代码达到指定长度自动折行
取消大小写匹配搜索🔍
代码变更后会改变文件夹的颜色
![image-20220325164304801](https://s2.loli.net/2022/03/25/X1HhgBMVvZDasWS.png)
去除打开时会打开上一次的项目
![image-20220325164451965](https://s2.loli.net/2022/03/25/ZA5hlpu8kYo46dC.png)
多行操作
![image-20220325164813810](https://s2.loli.net/2022/03/25/ad1T4DNQi5KBzRs.png)
比较文件
![image-20220325165100385](https://s2.loli.net/2022/03/25/kNOPxzdVwlTjBbu.png)
5.常用插件
四、配置项目参数
配置相关参数:
添加源断点,debug启动,结果如上图右侧终端中:
源断点添加:args+“\n”+System.getenv()+“\n”+System.getenv(“env”),为了输出相应的配置
相关代码:
import java.util.Arrays;
public class Memory {
public static void main(String[] args) {
//返回JVM试图使用的最大内存-->1/4
long maxMemory = Runtime.getRuntime().maxMemory();
//返回JVM初始化时的内存-->1/64
long totalMemory = Runtime.getRuntime().totalMemory();
System.out.println("字节"+maxMemory+" 内存"+maxMemory/(double)1024/1024+"MB");
System.out.println("字节"+totalMemory+" 内存"+totalMemory/(double)1024/1024+"MB");
//内存调优
//-Xms1024m -Xms1024m -XX:+PrintGCDetails
System.out.println(Arrays.toString(args)); //此处打源断点
}
}