- Windows 10, IntelliJ IDEA plugin SonarLint 10.8.1.79205
java.util.Scanner
has some constructors that don’t need closing. For example, you may be using an existing InputStream
that is already being closed, in which case Scanner is merely a wrapper that closes its underlying stream. As far as I know, it allocates no resources of its own; which is why the AutoCloseable interface is ambiguous by definition, as some users may believe that everything AutoCloseable needs to be closed, but that doesn’t seem to be so. Here is a comment criticizing the rule: Reddit - Dive into anything
In this example, only the FileInputStream is created that SonarLint should care about (it correctly interprets this when it’s wrapped in a Scanner). The creation of Scanner itself is no reason to close it.
Another example is a String constructor that uses StringReader. It supports close(), which merely makes the instance null (to prevent it from being used), but there is no resource de-allocation, GC seems to do all the work anyway. As you can see on SO, this becomes a self-proving loop where people cite SonarLint as the only reason for why it should be closed: java.util.scanner - Java Scanner with string input should be closed? - Stack Overflow
I’m pleasantly surprised that System.in is already considered to be an exception here; so you can just continue with more exceptions to this rule. All Scanner constructors need to be considered individually; for example Path
that allocates a Files.newInputStream(source)
internally definitely does need closing, because it’s a new resource allocation.
// Correct usage without close, no problem detected
new Scanner(System.in);
// False positive
new Scanner("test");
FileInputStream fileInputStream = new FileInputStream("test.txt");
try (fileInputStream) {
// False positive
new Scanner(fileInputStream);
}
// Correct usage, no problem detected
try (Scanner scanner = new Scanner(new FileInputStream("test.txt"))) {
}