Technology/Java

Scanner close 반드시 해야할까?

ikjo 2022. 2. 15. 21:02

그동안 관습적으로 close를 사용하지 않지 않았었다.

그동안 나는 Java 프로그래밍을 하면서 Scanner(System.in)로 키보드를 통해 사용자로부터 입력 받은 값을 읽어올 때 관습적으로 close를 하지 않는 습관이 있었다. 이때 사용자로부터 입력 받는 값은 Stream을 통해 입력받게 된다. 그런데 이 Stream 인스턴스를 다 사용하고 나서 close하지 않아도 과연 괜찮을까?

 

 

Java Stream 공식 문서를 살펴보자.

일단 자바 Stream 인터페이스에 대한 공식 문서에서는 Stream에 대해 다음과 같이 언급하고 있다.

 

Streams have BaseStream.close() method and implement AutoCloseable, but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files.lines(Path, Charset)) will require closing. Most streams are backed by collections, arrays, or generating functions, which require no special resource management. (If a stream does require closing, it can be declared as a resource in a try-with-resources statement.)

 

위 내용을 보면 대부분의 스트림들은 사용 이후에 close 될 필요가 없다고 한다. 이는 결론적으로 그동안 관습적으로 close를 사용하지 않고서도 프로그래밍을 할 때 예외 상황 없이 잘 돌아갔었던 이유를 방증하는 말이다.

 

다만, 소스가 IO(입출력) 채널인 스트림의 경우에는 close 할 필요가 있다고 하는데, 대표적으로 Files.lines(Path path, Charset cs)와 같이 스트림으로 파일 리소스를 읽어오는 경우가 있다.

 

그 이유는 하나의 스레드에서 스트림을 열어서 사용하는 중에는 다른 스레드가 접근할 수 없게 되는 상황 또는 파일이 손상(열어 놓고 닫지 않아)되는 현상이 발생하는 경우가 생길수도 있으므로 이를 방지하고자 하기 위함이 아닐까 싶다.

 

이처럼 close를 반드시 필요로 하는 스트림의 경우에는 close를 명시적으로 선언해주거나 try-with-resources 구문을 사용해야한다.

 

 

무조건 close 한다고 능사가 아니다.

어느 한 스택오버플로우 답변 자료에 따르면 Scanner(System.in)을 close 시킨다는 것은 Scanner 인스턴스 뿐만 아니라 System.in을 close하는 것과 같다고 한다. 이때 System.in이 close되면 reopen할 수 있는 것은 오직 JVM만이 가능하기 때문에 이후에 System.in으로부터 새로운 Scanner를 만들어서 사용하는 것이 불가능해진다. 즉, 특정 상황(막상 close를 했는데 Scanner를 다시 사용해야 하는 상황)에서는 무작정 Scanner를 close하는 것이 문제가 될 수 있을 것으로 보인다.

 

 

상황에 따라 "적절하게" 사용하자 😂

이처럼 무조건 close를 하는 게 좋다 무조건 close를 할 필요가 없다라기보다는 다양한 상황을 대비해 이같은 Stream과 close에 대한 개념을 잘 이해하고 있어 적절한 상황에 맞춰 사용할 수 있도록 하는 것이 중요할 것으로 생각된다.

 

 

참고자료

  • https://okky.kr/article/915691?note=2308988
  • https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
  • https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
  • https://stackoverflow.com/questions/58244954/why-cant-i-just-create-another-scanner-object-after-using-scanner-close
  • https://stackoverflow.com/questions/52040576/scanner-close-method-closes-all-scanners-why