为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以将 try 与资源和输入流一起使用?

是否可以将 try 与资源和输入流一起使用?

慕容森 2023-08-04 15:36:01
Scanner sc = new Scanner(System.in)当使用资源实现 try 时,我通过try 语句的 inside ()创建一个 Scanner 对象。在 try 块中,我提示用户输入一个数值,通过读取它sc.nextLine()并将parseDouble其转换为方法。如果最初输入的值无效,我会利用 do-while 循环重新提示用户输入值。但是,如果用户输入无效值,则输入流将关闭NumberFormatException并被捕获,但在 do-while 循环的第二次迭代期间,会抛出“未找到行”NoSuchElementException,并且由于“流已关闭”java.lang.NoSuchElementException 异常而被抛出。 io.IOException。有没有办法在利用资源尝试时规避这个问题?<?xml version="1.0" encoding="utf-8"?>    <androidx.constraintlayout.widget.ConstraintLayout        xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:app="http://schemas.android.com/apk/res-auto"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="horizontal"        android:padding="16dp">            <LinearLayout                android:id="@+id/a1"                android:layout_width="0dp"                app:layout_constraintWidth_percent=".48"                android:layout_height="0dp"                app:layout_constraintHeight_percent=".3"                android:background="@drawable/blacksquare"                app:layout_constraintStart_toStartOf="parent"                app:layout_constraintTop_toTopOf="parent"                android:padding="8dp"                android:orientation="horizontal">            </LinearLayout>            <LinearLayout                android:id="@+id/a2"                android:layout_width="0dp"                android:layout_height="0dp"                app:layout_constraintWidth_percent=".48"                app:layout_constraintHeight_percent=".3"                android:background="@drawable/blacksquare"                app:layout_constraintEnd_toEndOf="parent"                app:layout_constraintTop_toTopOf="parent"                android:padding="8dp"                android:orientation="horizontal">            </LinearLayout>    </androidx.constraintlayout.widget.ConstraintLayout>
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

您不应该将 try-with-resource 与您自己没有打开的资源一起使用,尤其是 with ,System.in它永远不应该被应用程序关闭。


除此之外,您应该更喜欢事先测试条件,而不是捕获异常。此外,尽量避免代码重复,您最终会得到一个更简单的解决方案:


public static void main(String[] args) {

    Scanner sc = new Scanner(System.in).useDelimiter("\\R");

    System.out.print("Enter first numeric value: ");

    double d1 = getDouble(sc);

    System.out.print("Enter second numeric value: ");

    double d2 = getDouble(sc);

    System.out.print("Choose an operation (+ - * /): ");

    while(!sc.hasNext("[-+*/]")) {

      System.out.println(sc.next()+" is not a valid operation");

    }

    String operation = sc.next();


    double result;

    switch (operation) {

        case "+": result = d1 + d2; break;

        case "-": result = d1 - d2; break;

        case "*": result = d1 * d2; break; 

        case "/": result = d1 / d2; break;

        default:

            throw new AssertionError("should not happen due to pretest");

    }

    System.out.println(d1+operation+d2);

    System.out.println("The answer is " + result);

}    

private static double getDouble(Scanner sc) {

    while(!sc.hasNextDouble()) {

        System.out.println(sc.next()+" is not a number");

    }

    return sc.nextDouble();

}

该解决方案用于hasNextDouble()询问扫描器下一个令牌是否具有双精度格式,并且只有在确认的情况下,应用程序才会通过 获取它nextDouble()。否则,它用于next()获取无效令牌,该令牌同时服务于报告并将其从未处理的输入中删除。同样,hasNext("[-+*/]")检查输入是否与支持的四个运算符之一匹配。


由于编译器不知道现在只能出现四个有效输入之一,因此我们必须在 的情况下放置一个抛出语句default,switch否则编译器会说result可能尚未初始化。我们可以初始化result为默认值,但如果程序流程未按预期工作,最好有一个强信号,而不是将默认值打印为错误结果。


使用Scanner可配置的分隔符来决定令牌的构成,因此该解决方案使用useDelimiter("\\R")换行符作为分隔符,将每一行视为一个令牌,就像原始代码一样。因此该类Pattern对语法进行了完整的描述。


查看完整回答
反对 回复 2023-08-04
  • 1 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信