# IDEA高级Debug技巧
-
条件断点(Conditional breakpoint): 允许开发者设置特定条件,只有当这些条件满足时,程序才会在这些断点处暂停执行。这对于调试复杂的循环和分支逻辑尤其有用,因为它可以让你聚焦于特定的执行路径或案例。
-
计算器(Evaluate Expression): 这个功能允许开发者在调试会话中计算表达式的值,不仅可以查看变量的当前值,还可以执行表达式,甚至调用方法。这对于验证假设和测试代码更改而无需重新启动整个调试会话非常有用。(查看变量值、修改变量值、测试表达式、执行方法调用)
# Java 隐藏特性:双花括号初始化实例,除非你想OOM
Map<String, String> map = new HashMap() {{
put("map1", "value1");
put("map2", "value2");
put("map3", "value3");
}};
这段代码其实是创建了匿名内部类,然后再进行初始化代码块。优雅的替换方案:
List<String> list = Stream.of("Java", "Redis").collect(Collectors.toList());
Map map = Map.of("map1", "Java", "map2", "Redis");
# 为什么IO流不关闭会导致内存泄漏
当IO流不关闭时,可能会导致以下对象无法被回收:
FileInputStream
或其他输入流对象:如果你没有关闭FileInputStream
对象,它会一直持有底层文件的句柄,这可能会导致文件资源无法释放。这样的对象将无法被垃圾回收器回收。FileOutputStream
或其他输出流对象:类似地,如果你没有关闭FileOutputStream
对象,它可能会持有底层文件的句柄,并且可能导致写入缓冲区中的数据无法刷新到磁盘。这可能会导致资源泄漏和数据丢失。Socket
或其他网络连接相关的对象:如果你没有关闭 Socket 或其他网络连接相关的对象,它们可能会保持与远程主机的连接状态,这会导致网络资源无法释放,这些对象将无法被垃圾回收器回收,同样也可能导致端口号占用导致其他线程无法使用该端口的情况。BufferedReader
、BufferedWriter
或其他缓冲流对象:如果你没有关闭这些缓冲流对象,它们可能会持有底层的输入流或输出流对象,并且可能会导致数据未能刷新或缓冲区数据未能清空。这可能会导致资源泄漏和数据丢失。
需要注意的是,即使没有显式地关闭这些对象,某些情况下它们可能会在垃圾回收器执行时被自动回收。但是,这取决于具体的垃圾回收算法和实现,所以我们不能依赖这种行为。正确的做法是在使用完这些对象后,显式地调用它们的 close()
方法来关闭流并释放相关资源,以防止资源泄漏和数据丢失。