Utilisation de try-with-resources avec System.in [duplicate]

Dec 12 2020

Donc, mon IDE se plaint si je ne place pas le scanner dans un try with block, mais si je le fais de cette façon au lieu de le fermer quand il est censé se fermer (une fois win = true), il ferme le flux System.in, comment éviter cela?

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);
}

Réponses

a.deshpande012 Dec 12 2020 at 03:19

Je recommanderais de ne pas avoir plusieurs Scannerobjets autour du même flux d'entrée. (dans ce cas, System.in) La raison en est que les scanners peuvent consommer et mettre en mémoire tampon les données du flux sous-jacent. Cela signifie que dans certains cas, des données peuvent être perdues. Vous pouvez en savoir plus dans cette question .

Vous pourrez peut-être vous en tirer ici, auquel cas vous ne devriez tout simplement pas fermer l'objet Scanner en ne l'enveloppant pas dans un essai avec des ressources. Dans ce cas, vous pouvez supprimer l'avertissement avec @SuppressWarnings("resource"). Cependant, c'est une mauvaise pratique.

Au lieu de cela, je recommanderais de créer un seul Scannerobjet global qui s'enroule System.in, puis de le transmettre à cette méthode en tant que paramètre au lieu de créer un nouveau scanner dans chaque méthode qui nécessite une entrée.

Andreas Dec 12 2020 at 03:16

comment éviter cela?

Ne fermez pas l' Scannerobjet, c'est-à-dire n'utilisez pas try-with-resources sur un Scannerwrapping System.in.

Au lieu de cela, acceptez l'avertissement et masquez-le, car il s'agit d'une exception spéciale aux règles normales de "ressource":

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

FYI: J'utilise Eclipse IDE, et "Entourer avec try-with-resources" n'est que la première option pour corriger l'avertissement: