try catch
注意
java变量的作用域分为四个级别:类级、对象实例级、方法级、块级。
块级变量就是定义在一个块({})内部的变量都是局部变量
try{}中try后面的{}就是一个块级作用域,所以内部定义的变量是局部变量。
所以如果在try内定义的is,os流,在finall内关闭会爆红,因为他们的生命周期只在try{}中。
解决方法:在try之前先定义好内容为null的io流和is流。
package com.resource_release;
import java.io.*;
/**
* 目标:学会用字节流完成文件的复制(支持一切文件类型的复制)
*/
public class TryCatchFinallyDemo01 {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
/*
这范围内出现异常,is和os管道还没被创建,
*/
//1.创建一个字节输入流管道与原视频接通
File f = new File("E:\\play\\donghua\\八尺大人怪谈-遭遇篇\\Hasshaku-sama1-engsub.mp4");
is = new FileInputStream(f);
//2.创建一个字节输出流管道与目标文件接通
os = new FileOutputStream("D:\\newHassshaku_sama.mp4");
//3.定义一个字节数组来转移数据
byte[] buffer = new byte[1024];
int len; //记录读取的字节数
while((len =is.read(buffer))!=-1){
os.write(buffer,0,len);
}
System.out.println("复制完成了!");
} catch (Exception e) {
e.printStackTrace();
}finally { //finally 甚至比return优先级还高
//无论代码是否正常结束,还是出现异常情况最后都会执行这里
try {
if(os!=null){os.close();} //如果爆红,是因为在try内定义的变量生命周期只在try的括号内,要把is和
} catch (IOException e) { // os先在try外面定义好这里才能识别,同时要做非空校验再关闭
e.printStackTrace();
}
try {
if(is!=null){is.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//拓展面试题
public static int test(int a,int b){
try {
int c = a/b;
// System.exit(0); //除非出现关闭虚拟机的情况,不然其他所有情况都会执行fianlly
return c;
} catch (Exception e) {
e.printStackTrace();
return -1; //代表计算出bug
}finally {
//哪怕上面有return语句,也要先执行,开发中不建议再这里找return,如果加了返回的永远是这里的数据
return 100; //会枪return ,返回100
}
}
}
JDK7对资源释放的简化
package com.resource_release;
import java.io.*;
/**
* 目标:学会用字节流完成文件的复制(支持一切文件类型的复制)
*/
public class TryCatchResourceDemo02 {
public static void main(String[] args) {
try ( //这里面只能放置资源对象(不是资源会报错),用完会关闭,自动调用资源对象的close方法(即使出现异常)
//资源都是实现了Closeable接口的
InputStream is = new FileInputStream("E:\\play\\donghua\\八尺大人怪谈-遭遇篇\\Hasshaku-sama1-engsub.mp4");
OutputStream os = new FileOutputStream("D:\\newHassshaku_sama.mp4");
//可以自己写一个类实现AutoCLoseable接口,并重写后放入
MyConenction conenction = new MyConenction(); //会自动调用资源的close方法
){
//3.定义一个字节数组来转移数据
byte[] buffer = new byte[1024];
int len; //记录读取的字节数
while((len =is.read(buffer))!=-1){
os.write(buffer,0,len);
}
System.out.println("复制完成了!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyConenction implements AutoCloseable{ //注意,要定义在主类外
@Override
public void close() throws Exception {
System.out.println("资源被成功释放");
}
}