try-with-resources

수박참외메론·2022년 10월 23일
0

자바 라이브러리에는 close() 메서드를 호출해 직접 닫아줘야 하는 자원들이 많다.(InputStream, OutputStream,java.sql.Connection 등등)
이런 자원닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기도 한다. 이런 자원들은 보통 finalizer을 활용하고는 있지만, 그리 믿을만하지 못하다.

try-finally

전통적으로 자원의 닫힘을 보장하는 수단으로 try-finally 수법을 많이 사용했다. 이 방법을 사용하면, 예외가 발생하거나 메서드에서 반환되는 경우에도 자원을 안전하게 반환할 수 있다는 장점을 가지고 있다.

static String firstLineOfFile(String path) throws IOException{
	BufferedReader br = new BufferedReader(new FileReader(path));
    try {
    	return br.readLine();
    } finally {
    	br.close();
    }
}

여기에 문제는 br이라는 객체자체에 문제가 생겨버리면 return br.readLine() 이 라인에서 오류가 발생하고, 마찬가지로 br.close(); 이 라인에서도 오류가 발생한다.

하지만 우리가 오류를 트래킹해보면 위에 오류는 try문으로 넘어가서 finally 오류만 보이므로 첫번째 오류는 확인할 수 없게되는 문제점이 발생한다. (일반적으로 첫번째 발생한 오류를 보고싶음)

근데 자원이 여러개라고 친다면?

static void copy(String src, String dst) throws IOException {
	InputStream in = new FileInputStream(src);
    try{
    	OutputStream out = new FileOutputStream(dst);
        try{
        	byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while((n=in.read(buf)) >= 0) out.write(buf, 0, n);
        } finally {
        	out.close();
        }
    
    } finally {
    	in.close();
    }
}

이거 근데 왜 try 하나에 안담고.. 이렇게 하는거지? 에러날까봐인가?

try-with-resources

static String firstLineOfFile(String path) throws IOException{
    try (BufferedReader br = new BufferedReader(new FileReader(path))){
    	return br.readLine();
    }
}
static void copy(String src, String dst) throws IOException {
	
    try(InputStream in = new FileInputStream(src);
    	OutputStream out = new FileOutputStream(dst)){
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while((n=in.read(buf)) >= 0) out.write(buf, 0, n);
    }
}

자연스럽게 객체의 scope를 정해두어 close() 함수를 사용하지 않고도 객체를 수거할 수 있는 아주 좋은 구조의 코드이다.

일단 두 코드 훨씬 간결하고 읽기수월하다.
앞서 말했던 br 객체에서 오류가 발생한다고 생각해보면 readLine함수에서 오류가 발생하게 된다.

profile
하루하루는 성실하게 인생전체는 되는대로

0개의 댓글