Java 我必须写“我必须”吗;BufferedReader…“;在每种方法中?

Java 我必须写“我必须”吗;BufferedReader…“;在每种方法中?,java,Java,我正在学习java编程。我是否必须编写BufferedReader br=newbufferedreader(newinputstreamreader(System.in))一次又一次地在每个我必须从用户那里获取输入的方法中?如果存在其他替代方案,请提出建议。您可以将其设置为静态变量: public static BufferedReader br = new BufferedReader(new InputStreamReader(System.

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

您可以将其设置为
静态变量:

public static BufferedReader br = 
                       new BufferedReader(new InputStreamReader(System.in));
并相应地从每个相关方法访问它

另外,请看一个实用程序类,它使从用户处读取输入变得更容易



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

这取决于,你可以将它作为参数传递给你的方法,或者让它像类atribute一样

public class Something {
     private BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));
}
或者甚至将其公开为静态变量,以便从其他类访问它

public static BufferedReader reader = new BufferedReader(new InputStreamReaddoinger(System.in));

也许您应该在设计应用程序时更加仔细地考虑

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

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

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


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

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

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

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

  • 将输出流作为参数传递给将使用它的每个方法,或
  • 让每个方法返回主程序将输出的字符串
对于主要的输入/输出方法,如“提示用户输入,直到他们输入有效值”,应将流作为参数传递,如下所示:

不正确:

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:");
    // [...]
}
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 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:");
    // [...]
}
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 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:");
    // [...]
}
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 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:");
    // [...]
}
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);
}
还有一个改进,我认为这更能说明你的问题。您可以创建一个factory类来为您实例化读写器:

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

您可以根据需要向其添加任意多个重载,因此只需调用一个函数即可从任何输入流,甚至其他可能的输入源(如文件)构造所需的输入流类型。要从
InputStream
获取
BufferedReader
,请调用
InputFactory.BufferedReader(myInputStream)
。虽然这还有点长,但eclipse中的自动完成功能可以帮助您快速进入,如果您只使用链式构造函数,则无法做到这一点。

“Extract method”是一个让您发现的杀手级功能。如果您反复编写相同的代码->将其重构为单独的方法。是的,坦率地说,Java没有为生成文件管道提供某种“工厂”,这有点愚蠢。为什么要将其作为类属性?如果它是类属性,则可以轻松创建不同的类来解决应用程序的不同问题。例如,一个管理逻辑的类和另一个只处理与用户交互的类。查看依赖注入。创建一个处理输入(封装BufferedReader内容)的类,并将该类注入控制器。稍后,您可以注入一个不同的类,例如,从数据库读取数据。这样的松耦合意味着,如果您更改了输入数据的方式,您的应用程序和业务逻辑就不需要更改。使用
静态
变量不是一个好主意,因为它会在系统的不同组件之间引入高度耦合。@mariosangio虽然我大体上同意您的看法,我不认为这句话是普遍正确的,并且在某种程度上依赖于OP的程序背景。我猜OP没有太多的经验,他必须编写的程序可能也不太复杂。然而,我认为最好强调这种方法可能存在的问题,以便他可以考虑其他解决方案,这些解决方案当然更详细,但可以导致更易于维护和更好的结构programs@MarcoForberg谢谢,修好了。我纠正了另一个错误:这些方法也需要是静态的,因为它们是从静态上下文调用的