Utilizzo di try-with-resources con System.in [duplicate]

Dec 12 2020

Quindi il mio IDE si lamenta se non racchiudo lo Scanner in una prova con blocco, ma se lo faccio in questo modo invece di chiuderlo quando dovrebbe chiudersi (una volta win = true), chiude il flusso System.in, come posso impedirlo?

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

Risposte

a.deshpande012 Dec 12 2020 at 03:19

Consiglierei di non avere più Scanneroggetti che avvolgono lo stesso flusso di input. (in questo caso System.in) La ragione di ciò è perché gli scanner possono utilizzare e memorizzare nel buffer i dati dal flusso sottostante. Ciò significa che in alcuni casi i dati possono essere persi. Puoi leggere di più a riguardo in questa domanda .

Potresti riuscire a farla franca qui, nel qual caso dovresti semplicemente non chiudere l'oggetto Scanner non avvolgendolo in una prova con risorse. In tal caso, puoi sopprimere l'avviso con @SuppressWarnings("resource"). Tuttavia, questa è una cattiva pratica.

Invece, consiglierei di creare un singolo Scanneroggetto globale che avvolge System.ine quindi passarlo a questo metodo come parametro invece di creare un nuovo scanner in ogni metodo che richiede input.

Andreas Dec 12 2020 at 03:16

come posso impedirlo?

Non chiudere l' Scanneroggetto, ovvero non utilizzare try-with-resources su un Scannerwrapping System.in.

Accetta invece l'avviso e nascondilo, poiché è un'eccezione speciale alle normali regole "risorsa":

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

FYI: Sto usando Eclipse IDE, e "Surround with try-with-resources" è solo la prima opzione per correggere l'avviso: