Home > database >  How to take input after closing scanner class (to fix resource leak) in java without re initializing
How to take input after closing scanner class (to fix resource leak) in java without re initializing

Time:05-05

I have this code to shift the elements of array since i was taking array input and printing them i created a java file for taking input and printing them code for that--

import java.util.*;

public class test_inp_out_array {
    public int[] inputArray(int n) {
        Scanner sc = new Scanner(System.in);
        int arr[] = new int[n];
        for (int i = 0; i < n; i  ) {
            arr[i] = sc.nextInt();
        }
        sc.close();
        return arr;
    }

public void printArray(int arr[]) {
    for (int i = 0; i < arr.length; i  ) {
        System.out.println(arr[i]);
    }
}
}

and i am using it in different files as methods in the --

import java.util.*;

public class cn_46_rotate_array {
    public static int[] shift(int arr[], int d) {//method to shift the elements 
        int temp[] = new int[d];
        for (int j = 0; j < d; j  ) {
            temp[j] = arr[j];
        }
        for (int i = 0, j = 0; i < arr.length && j < d; i  ) {
            if (i < arr.length - d) {
                arr[i] = arr[i   d];
            } else {
                arr[i] = temp[j];
                j  ;
            }
        }
        return arr;
    }
public static void main(String[] args) {
    Scanner ab = new Scanner(System.in);
    test_inp_out_array ch = new test_inp_out_array();
    int n = ab.nextInt();//total number of elements in array
    int d = ab.nextInt();//difference by which i want to shift elements in array
    int arr[] = ch.inputArray(n);
    int arr1[] = shift(arr, d);
    ch.printArray(arr1);
    ab.close();
}
}

the program works fine when written in this way but it throws this error when i take input of variable 'd' after calling method 'ch.inputArray'

Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)

    at java.base/java.util.Scanner.next(Scanner.java:1594)   
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)

    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)

    at cn_46_rotate_array.main(cn_46_rotate_array.java:25)  

the reason behind this is that i am closing scanner object 'sc' in my test_inp_array.java file when i call the method 'inputArray' which is also closing the input process in the file where im calling it so what should i do to avoid resource leak and take input of variable 'd' after storing the elements in array. what can be the other solution other than surrounding 'sc' object with try-with-resources in java.

CodePudding user response:

Various "linter" tools notice that you're making a resource object and that it must therefore be closed.

The linter is completely wrong. You should ignore the linter tool.

Resources are much more complex than that. Specifically, most autoclosables are actually so-called filter resources: They do not, themselves, hold any OS-level handles that require closing. Instead, they wrap around some other resource. There is no need to close such resources at all - but the underlying thing, that might need closing.

It's even more complicated: Whether you should close a resource in the first place depends on whether you have adopted the responsibility. When you write, for example, new FileInputStream(someFile), you're responsible. But when you write socket.getInputStream(), you're also responsible, and also if you write Files.newBufferedReader(), for example. But, other non-constructors that return resources do not imply you adopt responsibility. The docs will mention it. Generally, 'if you make it, you close it' is the throughline, but Files.getInputStream already breaks that rule. Hence why it is crucial to read the javadoc, it'll tell you if you're responsible for closing it.

The linter tools cannot read documentation and thus give incorrect advice.

Specifically: You do NOT have the responsibility of closing System.in, it is not a resource leak if you leave it open. Scanner is a filter resource. In other words, you should NOT close System.in, and, therefore, you should NOT close any scanner wrapped around System.in. If your linter tool says that you should, your linter tool is wrong.

With all that as intro, now I get to answer your question:

How to take input after closing scanner class

That is impossible.

Hence why you.. shouldn't close System.in.

  • Related