私はJavaを学んでいて、楽しみのためにいくつかのプロジェクトに取り組んでいます。私が遭遇した1つの問題は、Scanner
オブジェクトを使用するとEclipseが警告することです:
リソースリーク:「スキャン」は決して閉じられません。
そこで、コードの最後にscan.close();
を追加し、警告を処理します。
同じパッケージ内にスキャナーオブジェクトも使用する他のクラスがあり、Eclipseはそれらのクラスのスキャナーをそれぞれ閉じるように指示しているため、問題が発生します。ただし、そのようにすると、スキャナーオブジェクトがすべて閉じられ、実行時にエラーが発生するようです。
エラーの原因の例を次に示します。
_import Java.util.Scanner;
public class test2 {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int test = 0;
do {
//Do stuff
test = scan.nextInt();
System.out.println(test);
scanTest scanTest = new scanTest();
scanTest.test();
} while (test != 0);
scan.close();
}
}
import Java.util.Scanner;
public class scanTest {
public void test() {
Scanner scanner = new Scanner(System.in);
int blah = scanner.nextInt();
System.out.println(blah);
scanner.close();
}
}
_
スキャナーがscanTest
クラスで閉じられ、_test2
_のdoループに再び入ると、test = scan.nextInt();
の行でエラーが発生します
スキャナーオブジェクトの作成をdoループに移動して、毎回新しいオブジェクトを作成しようとしましたが、それでもエラーが発生します。
これがなぜ起こっているのか、または問題が発生することなくすべてのI/Oオブジェクトが確実に閉じられるようにする方法がわかりません。
出会ったある投稿で、_System.in
_を閉じると再び開くことはできないと述べました。この場合は、プログラムの最後でSystem.inのスキャナーオブジェクトが閉じられていることを確認し、他のクラスの他のスキャナー警告をすべて@suppressする必要がありますか?それとも、それらすべてのスキャナーオブジェクトを開いたままにしますか(悪い)?
まず、これはメモリリークではありません。
次に、ストリームラッパーを閉じると、デフォルトの実装では、ラップするストリームを閉じます。これは、スキャナーを(書かれているとおりに)初めて閉じるときに、はい、System.inを閉じることを意味します。
一般に、System.inから再度読み取る意味がある場合は、System.inを閉じないようにします。これを行う最善の方法は、プログラムによって異なります。
System.inからある種のバッファーに情報をコピーしてから、そのバッファーをスキャンすることができます。スキャナーを閉じず、他の場所で再利用する可能性があります。ガベージコレクションのためにスキャナーの参照を解除し、System.inに複数の新しいスキャナーを作成することもできます。
これらのソリューションはすべて同等ではなく、一部は他よりもはるかに優れていると考えられています。しかし、それはすべて呼び出しプログラムに依存します。いくつか試してみて、問題が発生した場合は、新しいStackOverflowの質問を開いて、コードの関連部分、問題の説明、入力例、および間違った出力(必要な出力とともに)を表示してください。
幸運を。
はい、スキャナーを閉じると、基になるストリーム(この場合はSystem.in)が閉じられます。これを回避するには、すべてのクラスで使用できるスキャナーのグローバル変数を作成するか、スキャナーをシャットダウンするための中心点を設定します(プログラムが終了する直前が理想的です)。
すべてのスキャナーに同じ名前を付けないでください。あなたがこのように複数のものを持っている場合:
_import Java.util.Random;
import Java.util.Scanner;
public class DayThree {
public static void main(String[] args) {
**Scanner textScanner = new Scanner(System.in);**
// boolean operands
// String(or objects) .equals() "this".equals("that") false
// primitive data types == 'a'=='a' -> true 5==6 false
// != 'a'!='a' -> false 5!=6 true
// ! !(true) -> false !(false) true
// > 5 > 4 -> true 'a' > 'b' false
// < 5 < 4 -> false
// <=
// >=
// && -> and 5 < 6 && 7 > 10 -> false
// if either side of and is false the outcome is false
// || -> or 5 < 6 || 7 > 10 -> true
// if either side of or is true the outcome is true
//System.out.println(!(5 < 10) && (7>3) || (true && false || true));
/* <-- this is a multi line comment
System.out.println("What is the most amazing show on tv this week? ");
String show = textScanner.nextLine().toLowerCase(); //this is case sensitive
show = show.toLowerCase(); // changes the strng to a lowercase version
show = show.toUpperCase();
if(show.equalsIgnoreCase("game of thrones")){ // .equalsIgnoreCase( ignores caps/lower)
System.out.println("Yes it is!");
}
else{
System.out.println("You are wrong.");
System.out.println(show + " is clearly inferior to Game of Thrones.");
}
System.out.println("Who is your favorite character in " + show + ".");
String character = textScanner.nextLine().toLowerCase();
if(character.contains("dragon")){
System.out.println("CGI magic is so cool!");
}
else if(character.contains("lanister")){
System.out.println("Wrong house.");
}
else{
System.out.println(character + "is pretty cool I guess...");
}
*/
// asdf alternate multi line comment use ctrl + / on highlighted text.
// doing this a second time undoes the comment
// sdaf
// asdf
// asdf
// asdf
// 1. ask about favorite something (pet)
// 2. save that into a string all lowercase
// 3. have a series of if else (x3) and else statements about the something
//NOTE: DO NOT END CONDITIONALS WITH ; example: if(boolean); IS WRONG.
**Scanner numScanner = new Scanner(System.in);** // the variable tells you what to use it for
Random Rand = new Random(); // this makes a new random object
System.out.println("Pick a number.");
int num = numScanner.nextInt();
int sNum = Rand.nextInt(9) + 1; // gives me a random num between 1-10
// nextInt(bound)gives you a num from 0-bound
//adding one gives you a num from 1 - bound + 1
if(num > sNum){
System.out.println("Too high");
System.out.println("The number was " + sNum);
}
else if(num < sNum){
System.out.println("Too low");
System.out.println("The number was " + sNum);
}
else{
System.out.println("Wow are you psychic? ");
}
textScanner.close();
numScanner.close();
}//main method
}
_
スキャナーごとに*scanner name goes here*.close();
を配置します。すべて同じ名前の場合は、他のスキャナーとは異なる処理を行うものを変更します。