又被System.out.print给坑了一把

发布于:2024-05-10 ⋅ 阅读:(34) ⋅ 点赞:(0)

学过java的同学都应该知道,第一个程序很多人都是这样:

public class Hello {

    public static void main(String[] args) {        

        System.out.print("Hello,world!");

    }
}

打印结果是:Hello,world!

接着可能会学习用户控制台输入Scanner的例子:

import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        System.out.println("请输入第一个整数:");

        // 创建Scanner对象用于接收用户输入
        Scanner scanner = new Scanner(System.in);        
        
        // 使用nextInt()方法读取一个整数
        int num1 = scanner.nextInt();
        
        System.out.println("请输入第二个整数:");
        // 再次使用nextInt()方法读取另一个整数
        int num2 = scanner.nextInt();
        
        // 计算两个整数的和
        int sum = num1 + num2;
        
        // 输出结果
        System.out.println("两个整数的和为:" + sum);
        
        // 关闭scanner
        scanner.close();
    }
}

这个代码很正常,提示用户输入两个整数,然后打印它们的和。

我把程序改成如下:

import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        // 创建Scanner对象用于接收用户输入
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("请输入第一个整数:");
        // 使用nextInt()方法读取一个整数
        int num1 = scanner.nextInt();
        
        System.out.println("请输入第二个整数:");
        // 再次使用nextInt()方法读取另一个整数
        int num2 = scanner.nextInt();
        
        // 计算两个整数的和
        int sum = num1 + num2;
        
        // 输出结果
        System.out.println("两个整数的和为:" + sum);
        
        // 关闭scanner
        scanner.close();
    }
}

使用vs code运行后竟然是这样:

第6行运行之后不应该停下来等我输入吗?怎么直接输出第8行的提示语句了啊?

查看了System的源码:

public final class System {
    /* Register the natives via the static initializer.
     *
     * The VM will invoke the initPhase1 method to complete the initialization
     * of this class separate from <clinit>.
     */
    private static native void registerNatives();
    static {
        registerNatives();
    }

    /** Don't let anyone instantiate this class */
    private System() {
    }

    /**
     * The "standard" input stream. This stream is already
     * open and ready to supply input data. Typically this stream
     * corresponds to keyboard input or another input source specified by
     * the host environment or user. In case this stream is wrapped
     * in a {@link java.io.InputStreamReader}, {@link Console#charset()}
     * should be used for the charset, or consider using
     * {@link Console#reader()}.
     *
     * @see Console#charset()
     * @see Console#reader()
     */
    public static final InputStream in = null;

    /**
     * The "standard" output stream. This stream is already
     * open and ready to accept output data. Typically this stream
     * corresponds to display output or another output destination
     * specified by the host environment or user. The encoding used
     * in the conversion from characters to bytes is equivalent to
     * {@link Console#charset()} if the {@code Console} exists,
     * <a href="#stdout.encoding">stdout.encoding</a> otherwise.
     * <p>
     * For simple stand-alone Java applications, a typical way to write
     * a line of output data is:
     * <blockquote><pre>
     *     System.out.println(data)
     * </pre></blockquote>
     * <p>
     * See the {@code println} methods in class {@code PrintStream}.
     *
     * @see     java.io.PrintStream#println()
     * @see     java.io.PrintStream#println(boolean)
     * @see     java.io.PrintStream#println(char)
     * @see     java.io.PrintStream#println(char[])
     * @see     java.io.PrintStream#println(double)
     * @see     java.io.PrintStream#println(float)
     * @see     java.io.PrintStream#println(int)
     * @see     java.io.PrintStream#println(long)
     * @see     java.io.PrintStream#println(java.lang.Object)
     * @see     java.io.PrintStream#println(java.lang.String)
     * @see     Console#charset()
     * @see     <a href="#stdout.encoding">stdout.encoding</a>
     */
    public static final PrintStream out = null;

    /**
     * The "standard" error output stream. This stream is already
     * open and ready to accept output data.
     * <p>
     * Typically this stream corresponds to display output or another
     * output destination specified by the host environment or user. By
     * convention, this output stream is used to display error messages
     * or other information that should come to the immediate attention
     * of a user even if the principal output stream, the value of the
     * variable {@code out}, has been redirected to a file or other
     * destination that is typically not continuously monitored.
     * The encoding used in the conversion from characters to bytes is
     * equivalent to {@link Console#charset()} if the {@code Console}
     * exists, <a href="#stderr.encoding">stderr.encoding</a> otherwise.
     *
     * @see     Console#charset()
     * @see     <a href="#stderr.encoding">stderr.encoding</a>
     */
    public static final PrintStream err = null;
    
    ......
}

来试图理解一下里面的流程:

System.in代表标准输入流,通常与键盘输入相关联。
System.out代表标准输出流,通常与控制台输出相关联。
程序启动之后,通过registerNatives()和设备进行关联。

我对这个设计的理解是,System.inSystem.out是在程序启动时就已经准备好的,并且会在程序的整个生命周期中保持可用状态。当程序需要读取用户输入或向控制台输出内容时,会使用这两个标准流对象来进行交互操作。因此,它们的执行顺序可以看作是在程序执行期间随时可用。

不知道对不对?

问题来源:

java用scanner类从控制台读取输入怎么可以先读取再提示呢?_编程语言-CSDN问答


网站公告

今日签到

点亮在社区的每一天
去签到