public static void maxintRecursive(int max) {
// create scanner
Scanner in = new Scanner(System.in);
// asks user for integer input
int a = in.nextInt();
// checks if integer input satisfies exit condition, closes scanner, prints max and returns
if (a <= 0) {
in.close();
System.out.println("Max int is: " max);
return;
}
// checks if input is greater than previous max registered int
if (a > max) {
max = a;
}
// calls itself again
maxintRecursive(max);
}
我可以成功編譯并運行它,但在第 3 行它強調“in”表示它從未關閉但是,此方法一直在呼叫自身,直到您達到退出條件(a <= 0),掃描儀實際上已關閉
這是一個錯誤嗎?它實際上永遠不會關閉并且我正在發生記憶體泄漏嗎?
我應該在主要方法中傳遞掃描儀,還是一樣?
此遞回方法要求用戶輸入一個整數,并在用戶輸入 0 或更少時回傳收到的最大整數
我在方法內部創建了一個掃描器,并在遞回方法達到其退出條件時將其關閉
我希望掃描器在退出條件下被我的代碼關閉,但 VS Code 說它永遠不會關閉
uj5u.com熱心網友回復:
每次呼叫方法時,它都會創建自己的區域變數。例如,如果您有類似的方法
void foo(int n) {
int x = n 1;
if (x < 2)
foo(x);
}
然后在執行時呼叫它foo(0);,它將有自己的兩個區域變數 n=0(方法引數)和x = n 1 = 0 1 = 1(在方法主體中宣告)。
然后,當您遞回呼叫時foo(x);,最終foo(1)呼叫將創建另一組將保存值的n x 區域變數n=1 x=2。
同樣,在您的情況下,每次呼叫maxintRecursive方法時,它都會創建自己的單獨Scanner in = new Scanner(...)物件。因此,如果您呼叫您的方法 N 次,則會Scanner創建 N 個物件(所有物件都從 中讀取System.in)。即使您呼叫in.close();方法處理if (a <= 0),它也只會關閉由該遞回呼叫創建的 Scanner。在之前的方法呼叫中創建的其他掃描儀將永遠不會關閉。
可能的解決方案也可以在您的方法末尾添加in.close();(在遞回呼叫之后),這將確保每個方法都會關閉自己的掃描儀。
但首選的解決方案是首先防止創建如此多的掃描儀。而是在main方法中創建一個并將其作為引數傳遞給遞回方法。因為它將被傳遞,所以Java 不會強制您在方法本身中關閉該掃描器,而是在創建它的范圍內(主要方法)。
為此,您需要通過修改其宣告來maxintRecursive 接受Scanner 作為引數,例如
public static void maxintRecursive(int max, Scanner in) {
//...
}
這樣你現在所需要的就是
public static main(String[] args){
Scanner scanner = new Scanner(System.in);
maxintRecursive(-1, scanner);
scanner.close();
}
順便說一句,我們避免創建在我們自己的方法內部處理的 Scanner 的另一個原因System.in是,通過該方法關閉此類 Scanner 也會關閉System.in。這意味著當您嘗試再次呼叫您的方法時,它將創建 Scanner,它將嘗試從 already close 中讀取System.in。同樣,在這種情況下,首選解決方案是將處理 System.in 的掃描儀作為方法引數傳遞。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/537113.html
上一篇:在深層嵌套陣列(樹)中查找遞回
下一篇:如何從字典生成配置組合?
