Java小白踩坑录 - B计划之Java资源如何释放?

简介: Java小白踩坑录 - B计划之Java资源如何释放?

image.png

Java中如何释放资源?

刚进公司时小白在学习 Java,碰到一个编程问题:文件操作关闭资源的时候,会莫名其妙的报错。代码如下:

publicvoidopenFile() throwsIOException {
FileReaderreader=newFileReader("someFile");
inti=0;
while(i!=-1){
i=reader.read();
System.out.println((char) i );
    }
reader.close();
System.out.println("--- File End ---");
 }

扫地僧针对小白刚刚编程的经历,采用循循诱导的方式。

扫地僧:上面的代码是不是没有捕获异常?是不是可以把异常捕获到,再分析异常原因?

小白:对哦,那我使用 try … catch 试试:

publicvoidopenFile(){
try {
// constructor may throw FileNotFoundExceptionFileReaderreader=newFileReader("someFile");
inti=0;
while(i!=-1){
//reader.read() may throw IOExceptioni=reader.read();
System.out.println((char) i );
 }
reader.close();
System.out.println("--- File End ---");
 } catch (FileNotFoundExceptione) {
//do something clever with the exception } catch (IOExceptione) {
//do something clever with the exception }
}

扫地僧:做的很不错,知道捕捉多重异常了,资源的关闭是不是放到 finally 比较好?

小白:对哦,我看语法有这样的,那我重新写一下:

publicvoidopenFile() throwsIOException {
FileReaderreader=null;
try {
reader=newFileReader("someFile");
inti=0;
while(i!=-1){
i=reader.read();
System.out.println((char) i );
    }
 } catch (FileNotFoundExceptione) {
//do something clever with the exception } catch (IOExceptione) {
//do something clever with the exception }finally {
reader.close();
System.out.println("--- File End ---");
 }
}

小白:哦,还忘掉 reader 的判断,再改一下:

publicvoidopenFile() throwsIOException {
FileReaderreader=null;
try {
reader=newFileReader("someFile");
inti=0;
while(i!=-1){
i=reader.read();
System.out.println((char) i );
    }
 } catch (FileNotFoundExceptione) {
//do something clever with the exception } catch (IOExceptione) {
//do something clever with the exception }finally {
if(reader!=null){
reader.close();
 }
reader.close();
System.out.println("--- File End ---");
 }
}

扫地僧:reader 的关闭,是不是还有可能抛出异常,是不是还要捕获?

小白:是哦,我忘记了,修改后的是这样的吗?

publicvoidopenFile() throwsIOException {
FileReaderreader=null;
try {
reader=newFileReader("someFile");
inti=0;
while(i!=-1){
i=reader.read();
System.out.println((char) i );
    }
 } catch (FileNotFoundExceptione) {
//do something clever with the exception } catch (IOExceptione) {
//do something clever with the exception }finally {
if(reader!=null){
try {
reader.close();
        } catch (IOExceptione) {
//do something clever with the exception        }
 }
reader.close();
System.out.println("--- File End ---");
 }
}

扫地僧:代码是不是太繁琐了?有没有更简洁的办法?让 Jvm 帮你处理一些繁琐的工作?

小白:听说过 try-with-resources,但没有用过。

扫地僧:那你看看这个是否简洁了一些呢?

publicvoidopenFile() throwsIOException {
Stringline;
try (BufferedReaderbr=newBufferedReader(
newFileReader("C:\\testing.txt"))) {
while ((line=br.readLine()) !=null) {
System.out.println(line);
            }
        } catch (IOExceptione) {
e.printStackTrace();
        }
}

从 JDK7 开始,使用 try-with-resources 可以自动释放资源,即把资源放到 try() 内部, JVM 会调用 java.lang.AutoCloseable.close() 方法,自动关闭 try() 内部的资源。

小白:厉害,我学会了。

扫地僧:那我考考你。

publicstaticvoidmain(String[] args) {
try {
System.out.println("Hello world");
return;
 } finally {
System.out.println("Goodbye world");
 }
}

这个会打印出什么结果?

小白:“hello world” ,因为 return 退出了,finally 不能执行。

扫地僧:不对,finally 总是会执行的,打印:

HelloworldGoodbyeworld

小白:我明白了,finally 总是会执行的。

扫地僧:那可不一定哦,看看这个:

publicstaticvoidmain(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
 } finally {
System.out.println("Goodbye world");
 }
}

小白:不是打印?

HelloworldGoodbyeworld

扫地僧:不论 try 语句块的执行是正常地还是意外地结束,finally 语句块确实都会执行。然而在这个程序中,try 语句块根本就没有结束其执行过程。System.exit 方法将停止当前线程和所有其他当场死亡的线程。finally 子句的出现并不能给予线程,继续去执行的特殊权限。如果想要执行,需要使用 ShutdownHook。JAVA中的ShutdownHook遇到进程挂掉的情况,且一些状态没有正确的保存下来,ShutdownHook可以在JVM关掉的时候执行一些清理现场的代码。

publicstaticvoidmain(String[] args) {
System.out.println("Hello world");
Runtime.getRuntime().addShutdownHook(
newThread() {
publicvoidrun() {
System.out.println("Goodbye world");
 }
 });
System.exit(0);
}

小白:好神奇!

扫地僧:学无止境,一起加油!今天到这里了!

目录
相关文章
|
3月前
|
Java API 开发工具
【Azure Developer】Java代码实现获取Azure 资源的指标数据却报错 "invalid time interval input"
在使用 Java 调用虚拟机 API 获取指标数据时,因本地时区设置非 UTC,导致时间格式解析错误。解决方法是在代码中手动指定时区为 UTC,使用 `ZoneOffset.ofHours(0)` 并结合 `withOffsetSameInstant` 方法进行时区转换,从而避免因时区差异引发的时间格式问题。
205 3
|
6月前
|
资源调度 安全 Java
Java 大数据在智能教育在线实验室设备管理与实验资源优化配置中的应用实践
本文探讨Java大数据技术在智能教育在线实验室设备管理与资源优化中的应用。通过统一接入异构设备、构建四层实时处理管道及安全防护双体系,显著提升设备利用率与实验效率。某“双一流”高校实践显示,设备利用率从41%升至89%,等待时间缩短78%。该方案降低管理成本,为教育数字化转型提供技术支持。
157 1
|
6月前
|
消息中间件 机器学习/深度学习 Java
java 最新技术驱动的智能教育在线实验室设备管理与实验资源优化实操指南
这是一份基于最新技术的智能教育在线实验室设备管理与实验资源优化的实操指南,涵盖系统搭建、核心功能实现及优化策略。采用Flink实时处理、Kafka消息队列、Elasticsearch搜索分析和Redis缓存等技术栈,结合强化学习动态优化资源调度。指南详细描述了开发环境准备、基础组件部署、数据采集与处理、模型训练、API服务集成及性能调优步骤,支持高并发设备接入与低延迟处理,满足教育机构数字化转型需求。代码已提供下载链接,助力快速构建智能化实验室管理系统。
169 44
|
5月前
|
前端开发 Java API
新手 Java 学习资料结合最新技术的精选推荐及高效学习资源参考
本文为新手推荐了涵盖Java基础到最新技术的学习资料,包括官方文档、在线课程、书籍、学习网站及实践平台,帮助系统掌握Java编程,并通过Spring Boot实战提升开发能力。
330 1
|
5月前
|
机器学习/深度学习 Java 大数据
Java 大视界 -- Java 大数据在智能政务公共资源交易数据分析与监管中的应用(202)
本篇文章深入探讨了 Java 大数据在智能政务公共资源交易监管中的创新应用。通过构建高效的数据采集、智能分析与可视化决策系统,Java 大数据技术成功破解了传统监管中的数据孤岛、效率低下和监管滞后等难题,为公共资源交易打造了“智慧卫士”,助力政务监管迈向智能化、精准化新时代。
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
254 9
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
292 2
|
Java 开发者
JAVA高手必备:URL与URLConnection,解锁网络资源的终极秘籍!
在Java网络编程中,URL和URLConnection是两大关键技术,能够帮助开发者轻松处理网络资源。本文通过两个案例,深入解析了如何使用URL和URLConnection从网站抓取数据和发送POST请求上传数据,助力你成为真正的JAVA高手。
244 11
|
安全 Java 网络安全
【认知革命】JAVA网络编程新视角:重新定义URL与URLConnection,让网络资源触手可及!
【认知革命】JAVA网络编程新视角:重新定义URL与URLConnection,让网络资源触手可及!
130 2
|
缓存 前端开发 Java
在Java项目中实现跨域资源共享(CORS)
在Java项目中实现跨域资源共享(CORS)