System.inでのtry-with-resourcesの使用[重複]

Dec 12 2020

したがって、私のIDEは、try with blockでスキャナーを囲まないと文句を言いますが、閉じるはずのときにスキャナーを閉じるのではなく、この方法で閉じると(win = trueの場合)、System.inストリームを閉じます。どうすればそれを防ぐことができますか?

public final void turn() {
    System.out.println("Enter your next move!");
    try (Scanner keyboard = new Scanner(System.in)) {
        final String move = keyboard.nextLine();
        if (move.isEmpty()) {
            won = true;
            return;
        }
        if (!validateFormat(move)) {
            System.out.println("Invalid format, try again.");
            return;
        }
        String[] moveAr;
        try {
            moveAr = move.split(",");
        } catch (PatternSyntaxException e) {
            System.out.println(e.getMessage());
            return;
        }
        try {
            validFields(moveAr);
        } catch (InvalidTurnException e) {
            System.out.println(e.getMessage());
            return;
        }
        final char colour = spielFeld.getField(getColumn(moveAr[0].charAt(0)),Character.getNumericValue(moveAr[0].charAt(1)) - 1).getColour();
        for (final String string : moveAr) {
            final int line = Character.getNumericValue(string.charAt(1)) - 1;
            final int column = getColumn(string.charAt(0));
            spielFeld.cross(column,line);
            final int columni = getColumn(string.charAt(0));
            if (spielFeld.columnCrossed(columni)) {
                points += crossedValues(string.charAt(0));
            }
        }
        if (spielFeld.colourComplete(colour)) {
            points += COLOUR_POINTS;
            coloursCrossed++;
        }
        if (coloursCrossed >= 2) {
            won = true;
        }
    }
    System.out.println("Momentane Punkte: " + points);
}

回答

a.deshpande012 Dec 12 2020 at 03:19

Scanner同じ入力ストリームを複数のオブジェクトでラップすることはお勧めしません。(この場合、System.in)これは、スキャナーが基になるストリームからのデータを消費してバッファリングする可能性があるためです。これは、場合によってはデータが失われる可能性があることを意味します。あなたはこの質問でそれについてもっと読むことができます。

ここでそれを回避できる可能性があります。その場合は、try-with-resourcesでラップせずにScannerオブジェクトを閉じないでください。その場合、で警告を抑制することができます@SuppressWarnings("resource")。ただし、これは悪い習慣です。

代わりに、Scannerラップアラウンドする単一のグローバルオブジェクトをSystem.in作成し、入力を必要とする各メソッドで新しいスキャナーを作成するのではなく、パラメーターとしてこのメ​​ソッドに渡すことをお勧めします。

Andreas Dec 12 2020 at 03:16

どうすればそれを防ぐことができますか?

Scannerオブジェクトを閉じないでください。つまり、Scannerラップしているオブジェクトでtry-with-resourcesを使用しないでくださいSystem.in

代わりに、警告を受け入れて非表示にします。これは、通常の「リソース」ルールの特別な例外であるためです。

@SuppressWarnings("resource")
Scanner keyboard = new Scanner(System.in);

参考:私はEclipse IDEを使用していますが、「Surround with try-with-resources」は、警告を修正するための最初のオプションにすぎません。