การใช้ try-with-resources กับ System.in [ซ้ำ]

Dec 12 2020

ดังนั้น IDE ของฉันจะบ่นถ้าฉันไม่ใส่เครื่องสแกนเนอร์ด้วยการลองบล็อก แต่ถ้าฉันทำแบบนี้แทนที่จะปิดเมื่อมันควรจะปิด (เมื่อชนะ = จริง) มันจะปิดสตรีม 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) สาเหตุเป็นเพราะสแกนเนอร์อาจใช้และบัฟเฟอร์ข้อมูลจากสตรีมที่อยู่เบื้องหลัง ซึ่งหมายความว่าในบางกรณีข้อมูลอาจสูญหายได้ คุณสามารถอ่านเพิ่มเติมได้ในคำถามนี้

คุณอาจจะหนีไปได้ที่นี่ซึ่งในกรณีนี้คุณไม่ควรปิดออบเจ็กต์เครื่องสแกนเนอร์โดยไม่ห่อหุ้มด้วยทรัพยากร @SuppressWarnings("resource")ในกรณีที่คุณสามารถปราบปรามการเตือนด้วย อย่างไรก็ตามนี่เป็นการปฏิบัติที่ไม่ดี

แต่ขอแนะนำให้สร้าง global Scannerobject เดียวที่ล้อมรอบSystem.inแล้วส่งต่อไปยัง method นี้เป็นพารามิเตอร์แทนการสร้างเครื่องสแกนใหม่ในแต่ละวิธีที่ต้องใช้ input

Andreas Dec 12 2020 at 03:16

ฉันจะป้องกันได้อย่างไร

อย่าใกล้ชิดScannerวัตถุคือไม่ได้ใช้ลองกับทรัพยากรบนที่เป็นห่อScannerSystem.in

ให้ยอมรับคำเตือนและซ่อนไว้แทนเนื่องจากเป็นข้อยกเว้นพิเศษสำหรับกฎ "ทรัพยากร" ปกติ:

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

FYI:ฉันใช้ Eclipse IDE และ "Surround with try-with-resources" เป็นเพียงตัวเลือกแรกในการแก้ไขคำเตือน: