如何在 java 中关闭扫描器 class(修复资源泄漏)后获取输入而不重新初始化它
How to take input after closing scanner class (to fix resource leak) in java without re initializing it
我有这个代码来移动数组的元素,因为我正在获取数组输入并打印它们我创建了一个 java 文件来获取输入并打印它们
代码--
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]);
}
}
}
我在不同的文件中使用它作为 --
中的方法
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();
}
}
以这种方式编写时程序运行良好,但是当我在调用方法 'ch.inputArray'
后输入变量 'd' 时会抛出此错误
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)
这背后的原因是,当我调用方法 'inputArray' 时,我正在关闭我的 test_inp_array.java 文件中的扫描器对象 'sc',这也关闭了文件中的输入进程我正在调用它,所以我应该怎么做才能避免资源泄漏并在将元素存储在数组中后输入变量 'd' 。除了在 java.
中用 try-with-resources 包围 'sc' 对象之外,还有什么其他解决方案
各种“linter”工具注意到您正在创建资源对象,因此必须关闭它。
linter 完全错误。您应该忽略 linter 工具。
资源比这复杂得多。具体来说,大多数可自动关闭的实际上是 so-called 过滤器资源:它们本身不持有任何需要关闭的 OS-level 句柄。相反,它们环绕着一些其他资源。 根本不需要关闭此类资源 - 但底层的东西可能需要关闭。
更复杂的是:你是否应该首先关闭资源取决于你是否承担了责任。例如,当您写 new FileInputStream(someFile)
时,您就有责任。但是当你写 socket.getInputStream()
时,你也有责任,例如,如果你写 Files.newBufferedReader()
也是如此。但是,其他 non-constructors return 资源 并不 暗示您承担责任。文档会提到它。一般来说,'if you make it, you close it'是直通线,但Files.getInputStream
已经打破了这个规则。因此,为什么阅读 javadoc 至关重要,它会告诉您是否负责关闭它。
linter 工具无法读取文档,因此会给出不正确的建议。
具体来说:您没有责任关闭System.in
,如果您保持打开状态,这不是资源泄漏。 Scanner
是一个过滤器资源。换句话说,您不应该关闭 System.in
,因此,您不应该关闭围绕 System.in
的任何扫描器。如果您的 linter 工具说您应该这样做,那么您的 linter 工具是错误的。
介绍了这么多,现在我来回答你的问题:
How to take input after closing scanner class
那是不可能的。
因此,为什么你..不应该关闭 System.in。
我有这个代码来移动数组的元素,因为我正在获取数组输入并打印它们我创建了一个 java 文件来获取输入并打印它们 代码--
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]);
}
}
}
我在不同的文件中使用它作为 --
中的方法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();
}
}
以这种方式编写时程序运行良好,但是当我在调用方法 'ch.inputArray'
后输入变量 'd' 时会抛出此错误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)
这背后的原因是,当我调用方法 'inputArray' 时,我正在关闭我的 test_inp_array.java 文件中的扫描器对象 'sc',这也关闭了文件中的输入进程我正在调用它,所以我应该怎么做才能避免资源泄漏并在将元素存储在数组中后输入变量 'd' 。除了在 java.
中用 try-with-resources 包围 'sc' 对象之外,还有什么其他解决方案各种“linter”工具注意到您正在创建资源对象,因此必须关闭它。
linter 完全错误。您应该忽略 linter 工具。
资源比这复杂得多。具体来说,大多数可自动关闭的实际上是 so-called 过滤器资源:它们本身不持有任何需要关闭的 OS-level 句柄。相反,它们环绕着一些其他资源。 根本不需要关闭此类资源 - 但底层的东西可能需要关闭。
更复杂的是:你是否应该首先关闭资源取决于你是否承担了责任。例如,当您写 new FileInputStream(someFile)
时,您就有责任。但是当你写 socket.getInputStream()
时,你也有责任,例如,如果你写 Files.newBufferedReader()
也是如此。但是,其他 non-constructors return 资源 并不 暗示您承担责任。文档会提到它。一般来说,'if you make it, you close it'是直通线,但Files.getInputStream
已经打破了这个规则。因此,为什么阅读 javadoc 至关重要,它会告诉您是否负责关闭它。
linter 工具无法读取文档,因此会给出不正确的建议。
具体来说:您没有责任关闭System.in
,如果您保持打开状态,这不是资源泄漏。 Scanner
是一个过滤器资源。换句话说,您不应该关闭 System.in
,因此,您不应该关闭围绕 System.in
的任何扫描器。如果您的 linter 工具说您应该这样做,那么您的 linter 工具是错误的。
介绍了这么多,现在我来回答你的问题:
How to take input after closing scanner class
那是不可能的。
因此,为什么你..不应该关闭 System.in。