我正在学习java编程。我是否必须BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
在必须从用户那里获取输入的每种方法中一次又一次地编写?如果存在其他替代方案,请提出建议。
4 回答
可能您应该更仔细地考虑应用程序的设计。
通常将与用户的交互和应用程序的逻辑分开是一个非常好的主意。
理想情况下,您将有一个类封装 aBufferedReader
和要打印到控制台的内容,并提供方法来获取您需要的输入并向用户显示他应该注意的信息。
为了完成这项工作,您必须创建该类的新实例并将其传递给需要与用户交互的所有类。
通过这种方式,您可以清楚地分离应用程序的不同关注点,这种分离将提高应用程序的可维护性。例如,如果除了文本用户界面之外还需要编写图形用户界面,会发生什么情况。
根据您的用例,有两种可能的答案:
如果您使用输出流进行调试,请做任何您喜欢的事情(只要它适合您),这是您的代码。其他用户的答案适用于此。
但是,如果您将其用于实际程序,则应执行以下操作之一:
- 将输出流作为参数传递给将使用它的每个方法,或者
- 让每个方法返回一个主程序将输出的字符串。
对于主要的输入/输出方法,例如“提示用户输入直到他们输入有效值”,您应该将流作为参数传递,如下所示:
不正确:
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 中的自动完成功能可以帮助您快速输入它,如果您只使用链式构造函数,它就不会那么好。
您可以将其static
设为变量:
public static BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
并相应地从每个相关方法访问它。
另外,看看Scanner
,一个实用程序类,它可以更轻松地读取用户的输入。
正如@mariosangiorgio 指出的那样,重要的是要考虑程序的哪些部分在做什么。您通常应该将代码分成逻辑一致的块,这意味着将处理 I/O 的代码与处理核心逻辑的代码分开。因此,在设计任何严肃的应用程序时,static
-variable 方法可能不是最好的方法,因为它可能会在某些情况下破坏这种“代码分离”的理念。尽管如此,对于刚刚学习的人来说,这应该没有问题。
这取决于,您可以将其作为参数传递给您的方法或使其具有类属性,例如
public class Something {
private BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));
}
甚至将其设为公共静态变量,以便从其他类访问它
public static BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));