Korzystanie z zasobów typu Try-with-Resources w System.in [duplicate]

Dec 12 2020

Więc moje IDE narzeka, jeśli nie załączam skanera do próby z blokiem, ale jeśli zrobię to w ten sposób, zamiast zamykać go, gdy ma się zamknąć (Once win = true), zamyka strumień System.in, jak temu zapobiec?

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

Odpowiedzi

a.deshpande012 Dec 12 2020 at 03:19

ScannerOdradzałbym zawijanie wielu obiektów wokół tego samego strumienia wejściowego. (w tym przypadku System.in) Przyczyną tego jest fakt, że skanery mogą pobierać i buforować dane z bazowego strumienia. Oznacza to, że w niektórych przypadkach dane mogą zostać utracone. Więcej na ten temat przeczytasz w tym pytaniu .

Możesz tu ujść na sucho, w takim przypadku nie powinieneś po prostu zamykać obiektu Scanner, nie pakując go w próbę z zasobami. W takim przypadku możesz wyłączyć ostrzeżenie za pomocą @SuppressWarnings("resource"). Jednak jest to zła praktyka.

Zamiast tego zalecałbym utworzenie pojedynczego Scannerobiektu globalnego, który jest zawijany System.in, a następnie przekazanie go do tej metody jako parametru zamiast tworzenia nowego skanera w każdej metodzie, która wymaga danych wejściowych.

Andreas Dec 12 2020 at 03:16

jak temu zapobiec?

Nie zamykaj Scannerobiektu, tj. Nie używaj try-with-resources na Scanneropakowaniach System.in.

Zamiast tego zaakceptuj ostrzeżenie i ukryj je, ponieważ jest to specjalny wyjątek od normalnych reguł dotyczących zasobów:

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

Do Twojej wiadomości: Używam Eclipse IDE i to „Surround with try-with-resources” to tylko pierwsza opcja naprawy ostrzeżenia: