2021. 8. 5. 09:12ㆍ카테고리 없음
use
api 를 사용해서 사용이 완료된 resource 를 닫자.
우리가 사용하는 자원들 중에서는 사용완료 후 사용상태를 중지로 바꾸지 않는 자원들이 있습니다. 그리고 우리는 close
method 등을 통해서 해당 자원의 상태를 사용하지 않는 상태로 바꾸어 줘야합니다.
Kotlin/JVM 에서 사용하는 자바의 표준 라이브러리는 이런 자원들을 많이 포함하고 있습니다. 대표적으로 다음 리소스들의 경우 자동으로 자원의 반환이 이루어지지 않습니다.
- InputStream and OutputStream
- Java.sql.Connection
- Java.io.Reader ( FileReader, BufferedReader, CSSParser )
- Java.new.Socket and java.util.Scanner
해당하는 모든 자원들은 AutoCloseable
을 상속받는 Closeable
인터페이스를 지원합니다.
다음 구문을 확인해봅니다.
fun countCharactersInFile(path:String):Int{
val reader = BufferedReader(FileReader(path))
try {
return reader.lineSequence().sumBy { it.length }
}
finally {
reader.close()
}
}
위의 구문은 복잡하고, 올바르지 않습니다. 왜냐하면, finally
블록에서 reader.close() 가 에러를 발생시킬 경우 처리할 수 없기 때문입니다. 이를 처리한다면, 다음처럼 바뀔 수 있다고 생각합니다.
fun countCharactersInFile(path:String):Int{
val reader = BufferedReader(FileReader(path))
try {
return reader.lineSequence().sumBy { it.length }
}
finally {
try { reader.close() } catch (e: Exception) {}
}
}
이런 구현은 길고 복잡하지만 일반적이기 떄문에 표준라이브러리 함수에서 use
로 추출했습니다. 이는 코틀린 버전 1.2
이상부터 지원됩니다.
책에 있는 예제와 함께 참고할 예제를 실어 봅니다.
try {
Socket("open", 80).use { socket ->
socket.getInputStream().use { inputStream ->
InputStreamReader(inputStream).use { reader ->
println(reader.readLines())
}
}
}
} catch (e: Exception) {
// ...
}
use
사용시 중첩해서 사용하게될 경우 it
로 하게되면 문제가 있을 수 있으니, 스콥에 맞추어 선언해 사용하기를 권장합니다.
try with resources
우리가 익숙한 try catch 로 자원을 핸들링하는 것은 코드가 때로는 복잡해지고 지저분해집니다. 이를 위해 지원되는 기능이 try with resources 입니다. 짧게 설명하면, try 에 사용한 자원을 try
블록이 종료될때 자동으로 Close 처리해줍니다.
public static String getHtml(String url) throws IOException {
val targetUrl = URL(url);
try (val inputSR = new InputStreamReader(targetUrl.openStream());val bufferReader = BufferedReader(inputSR)){
val html = StringBuffer();
var tmp;
while ((tmp = reader.readLine()) != null) {
html.append(tmp);
}
return html.toString();
}
}