众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故。
在Java的江湖中,存在着一种名为finally的功夫,它可以保证当你习武走火入魔之时,还可以做一些自救的操作。在远古时代,处理资源关闭的代码通常写在finally块中。然而,如果你同时打开了多个资源,那么将会出现噩梦般的场景:
public class Demo {
public static void main(String[] args) {
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
try {
bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")));
int b;
while ((b = bin.read()) != -1) {
bout.write(b);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (bin != null) {
try {
bin.close();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (bout != null) {
try {
bout.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
我们用try-with-resource来改写刚才的例子:
public class TryWithResource {
public static void main(String[] args) {
try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
int b;
while ((b = bin.read()) != -1) {
bout.write(b);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
示例:
public class AppTest {
public static void main(String[] args){
try(Connection con = new Connection()) {
con.print();
}catch (Exception e){
e.printStackTrace();
}
}
static class Connection implements AutoCloseable{
public void print(){
System.err.println("print data==>");
}
@Override
public void close() throws Exception {
System.err.println("auto close===>");
}
}
}
语法糖原理:
public class AppTest {
public AppTest() {
}
public static void main(String[] args) {
try {
AppTest.Connection con = new AppTest.Connection();
Throwable var2 = null;
try {
con.print();
} catch (Throwable var12) {
var2 = var12;
throw var12;
} finally {
if (con != null) {
if (var2 != null) {
try {
con.close();
} catch (Throwable var11) {
var2.addSuppressed(var11);
}
} else {
con.close();
}
}
}
} catch (Exception var14) {
var14.printStackTrace();
}
}
static class Connection implements AutoCloseable {
Connection() {
}
public void print() {
System.err.println("print data==>");
}
public void close() throws Exception {
System.err.println("auto close===>");
}
}
}