2

我正在学习java编程。我是否必须BufferedReader br = new BufferedReader(new InputStreamReader(System.in));在必须从用户那里获取输入的每种方法中一次又一次地编写?如果存在其他替代方案,请提出建议。

4

4 回答 4

2

可能您应该更仔细地考虑应用程序的设计。

通常将与用户的交互和应用程序的逻辑分开是一个非常好的主意。

理想情况下,您将有一个类封装 aBufferedReader和要打印到控制台的内容,并提供方法来获取您需要的输入并向用户显示他应该注意的信息。

为了完成这项工作,您必须创建该类的新实例并将其传递给需要与用户交互的所有类。

通过这种方式,您可以清楚地分离应用程序的不同关注点,这种分离将提高应用程序的可维护性。例如,如果除了文本用户界面之外还需要编写图形用户界面,会发生什么情况。

于 2013-06-26T20:14:51.680 回答
1

根据您的用例,有两种可能的答案:

如果您使用输出流进行调试,请做任何您喜欢的事情(只要它适合您),这是您的代码。其他用户的答案适用于此。

但是,如果您将其用于实际程序,则应执行以下操作之一:

  • 将输出流作为参数传递给将使用它的每个方法,或者
  • 让每个方法返回一个主程序将输出的字符串。

对于主要的输入/输出方法,例如“提示用户输入直到他们输入有效值”,您应该将流作为参数传递,如下所示:

不正确:

public static void main(String[] args){
    promptUserForInput();
}
public static int promptUserForInput(){
    Scanner in = new Scanner(System.console().reader());
    PrintWriter out = System.console().writer();
    out.print("Enter an integer:");
    // [...]
}

正确的:

public static void main(String[] args){
    promptUserForInput(System.console());
}
public static int promptUserForInput(Console io){
    Scanner in = new Scanner(io.reader());
    PrintWriter out = io.writer();
    out.print("Enter an integer:");
    // [...]
}

在另一种情况下,该方法不需要与用户进行实时交互,它应该返回一个String交互方法将使用的对象。

不正确:

public static void main(String[] args){
    printMsg("bob", "tuna fish", "pickles", "rye");
}
public static String printMsg(String person, String type, String topping, String bread){
    System.out.printf("%1$s wants a %2$s sandwich with %3$s on %4$s bread%n",
            person, type, topping, bread);
}

正确的:

public static void main(String[] args){
    System.out.println(generateMsg("bob", "tuna fish", "pickles", "rye"));
}
public static String generateMsg(String person, String type, String topping, String bread){
    return String.format("%1$s wants a %2$s sandwich with %3$s on %4$s bread",
            person, type, topping, bread);
}

还有另一项改进,我认为这更能说明您的问题。你可以创建一个工厂类来为你实例化你的读者和作者:

public class InputFactory {
    public static InputStreamReader inStreamReader(InputStream in){
        return new InputStreamReader(in);
    }
    public static BufferedReader bufferedReader(InputStream in){
        return new BufferedReader(inStreamReader(in));
    }
    public static Scanner scanner(InputStream in){
        return new Scanner(inStreamReader(in));
    }
}

您可以根据需要添加任意数量的重载,因此您可以只调用一个函数来从任何输入流甚至其他潜在输入源(如文件)构造所需的输入流类型。BufferedReader要从 中获取 a InputStream,请致电InputFactory.bufferedReader(myInputStream)。虽然这仍然有点长,但 Eclipse 中的自动完成功能可以帮助您快速输入它,如果您只使用链式构造函数,它就不会那么好。

于 2013-06-26T20:40:30.453 回答
0

您可以将其static设为变量:

public static BufferedReader br = 
                       new BufferedReader(new InputStreamReader(System.in));

并相应地从每个相关方法访问它。

另外,看看Scanner,一个实用程序类,它可以更轻松地读取用户的输入。


正如@mariosangiorgio 指出的那样,重要的是要考虑程序的哪些部分在做什么。您通常应该将代码分成逻辑一致的块,这意味着将处理 I/O 的代码与处理核心逻辑的代码分开。因此,在设计任何严肃的应用程序时,static-variable 方法可能不是最好的方法,因为它可能会在某些情况下破坏这种“代码分离”的理念。尽管如此,对于刚刚学习的人来说,这应该没有问题。

于 2013-06-26T20:02:05.063 回答
0

这取决于,您可以将其作为参数传递给您的方法或使其具有类属性,例如

public class Something {
     private BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));
}

甚至将其设为公共静态变量,以便从其他类访问它

public static BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));
于 2013-06-26T20:03:29.163 回答