
第4章 输入、输出和命令行交互前几章的代码大多把数据写死在程序里intage18;Stringname小林;这样能练语法但不是真正的交互程序。真实程序通常需要从外部接收数据用户输入姓名、输入成绩、输入菜单选项程序再根据输入做处理。这一章要解决三个问题Java 怎么把内容输出给用户看。Java 怎么从键盘读取用户输入。输入不合法时程序为什么会崩以及怎么防。学完本章后你就能写简单的命令行交互程序。一、输出println 和 print最常用输出System.out.println(Hello Java);println会输出内容并换行。System.out.println(第一行);System.out.println(第二行);输出第一行 第二行print不换行System.out.print(姓名);System.out.print(小林);输出姓名小林它们的区别方法是否换行常见用途println换行输出结果、日志、提示print不换行输出输入提示如请输入姓名比如System.out.print(请输入姓名);用户会在同一行输入。二、格式化输出让内容更清楚字符串拼接可以输出Stringname小林;intage18;System.out.println(姓名name年龄age);也可以用printfSystem.out.printf(姓名%s年龄%d%n,name,age);常见占位符占位符含义%s字符串%d整数%f小数%.2f保留两位小数%n换行示例doubleprice19.9;System.out.printf(价格%.2f元%n,price);输出价格19.90元入门阶段你可以先主要用字符串拼接遇到金额、平均分这类需要控制小数位的再用printf。三、Scanner从键盘读取输入Java 读取命令行输入常用Scanner。importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){ScannerscannernewScanner(System.in);System.out.print(请输入姓名);Stringnamescanner.nextLine();System.out.println(你好name);}}拆开看importjava.util.Scanner;表示导入 Scanner 类。Java 标准库里有很多类用到时要导入。ScannerscannernewScanner(System.in);创建一个 Scanner让它从标准输入System.in读取数据。标准输入通常就是键盘。Stringnamescanner.nextLine();读取用户输入的一整行文本。四、读取不同类型的数据读取字符串Stringnamescanner.nextLine();读取整数intagescanner.nextInt();读取小数doubleheightscanner.nextDouble();完整示例importjava.util.Scanner;publicclassProfileInput{publicstaticvoidmain(String[]args){ScannerscannernewScanner(System.in);System.out.print(请输入姓名);Stringnamescanner.nextLine();System.out.print(请输入年龄);intagescanner.nextInt();System.out.print(请输入身高);doubleheightscanner.nextDouble();System.out.println(姓名name);System.out.println(年龄age);System.out.println(身高height);}}运行后程序会停下来等待用户输入。这和前面写死变量不一样。五、nextLine 和 nextInt 混用的坑看这段代码ScannerscannernewScanner(System.in);System.out.print(请输入年龄);intagescanner.nextInt();System.out.print(请输入姓名);Stringnamescanner.nextLine();System.out.println(姓名name);System.out.println(年龄age);你可能发现输入年龄后姓名还没来得及输入程序就结束了。原因是nextInt()读取数字但不会吃掉最后的换行符。后面的nextLine()读到了那个残留换行于是得到空字符串。解决方式在nextInt()后面补一次nextLine()吃掉换行。System.out.print(请输入年龄);intagescanner.nextInt();scanner.nextLine();System.out.print(请输入姓名);Stringnamescanner.nextLine();另一种方式是所有输入都用nextLine()读取字符串再自己转换System.out.print(请输入年龄);StringageTextscanner.nextLine();intageInteger.parseInt(ageText);这种方式更统一也更适合后面做错误处理。六、输入不合法会怎样如果代码是intagescanner.nextInt();用户输入abc程序会抛出异常InputMismatchException因为abc不能当作整数读取。如果使用StringageTextscanner.nextLine();intageInteger.parseInt(ageText);用户输入abc会出现NumberFormatException两种本质一样输入和程序期待的类型不匹配。第一阶段我们先用简单方式处理先判断字符串是否像数字。publicstaticbooleanisInteger(Stringtext){if(textnull||text.isEmpty()){returnfalse;}for(inti0;itext.length();i){charchtext.charAt(i);if(ch0||ch9){returnfalse;}}returntrue;}使用System.out.print(请输入年龄);StringageTextscanner.nextLine();if(!isInteger(ageText)){System.out.println(年龄必须是整数);return;}intageInteger.parseInt(ageText);这里我们还没系统讲方法但你可以先看到把校验逻辑拆成方法主流程会更清楚。七、命令行参数和 Scanner 的区别上一章讲过String[] argsjavaArgsDemo Tom18参数在程序启动时就给好。Scanner 是程序运行过程中再让用户输入。对比方式数据什么时候进入程序适合场景String[] args启动程序时脚本参数、配置项、一次性命令Scanner程序运行中菜单、交互、用户逐步输入命令行参数示例publicclassArgsProfile{publicstaticvoidmain(String[]args){if(args.length2){System.out.println(用法java ArgsProfile 姓名 年龄);return;}Stringnameargs[0];intageInteger.parseInt(args[1]);System.out.println(nameage);}}Scanner 示例ScannerscannernewScanner(System.in);System.out.print(请输入姓名);Stringnamescanner.nextLine();第一阶段的交互项目主要用 Scanner。八、做一个注册信息输入程序需求输入姓名。输入年龄。输入手机号。判断姓名不能为空。判断年龄是否是整数。判断手机号长度是否为 11。输出注册结果。代码importjava.util.Scanner;publicclassRegisterInputDemo{publicstaticvoidmain(String[]args){ScannerscannernewScanner(System.in);System.out.print(请输入姓名);Stringnamescanner.nextLine();if(namenull||name.isEmpty()){System.out.println(姓名不能为空);return;}System.out.print(请输入年龄);StringageTextscanner.nextLine();if(!isInteger(ageText)){System.out.println(年龄必须是整数);return;}intageInteger.parseInt(ageText);if(age18){System.out.println(未满18岁不能注册);return;}System.out.print(请输入手机号);Stringphonescanner.nextLine();if(phonenull||phone.length()!11){System.out.println(手机号必须是11位);return;}System.out.println(注册成功);System.out.println(姓名name);System.out.println(年龄age);System.out.println(手机号phone);}publicstaticbooleanisInteger(Stringtext){if(textnull||text.isEmpty()){returnfalse;}for(inti0;itext.length();i){charchtext.charAt(i);if(ch0||ch9){returnfalse;}}returntrue;}}这段代码已经有一点真实程序的样子了数据来自用户输入。输入后先校验。不合法就提前 return。合法才继续后续流程。把整数判断拆成方法。九、为什么要先校验再使用很多新手会直接intageInteger.parseInt(scanner.nextLine());用户输入正确时没问题。但用户输入abc程序直接崩。更稳的流程读取原始输入 - 校验 - 转换 - 使用代码StringageTextscanner.nextLine();if(!isInteger(ageText)){System.out.println(年龄格式错误);return;}intageInteger.parseInt(ageText);这个思维非常重要。以后处理网络、文件、数据库也是一样外部输入永远不要默认可信。十、常见错误1. 忘记导入 ScannerScannerscannernewScanner(System.in);如果没有importjava.util.Scanner;会编译失败。2. nextInt 和 nextLine 混用读取数字后又读取整行可能读到残留换行。解决方式是补scanner.nextLine()或者统一用nextLine()。3. 输入类型不匹配用户输入 abc但程序按 int 读取会异常。4. 没校验空字符串Stringnamescanner.nextLine();用户直接回车name 是空字符串不是 null。要用name.isEmpty()5. 把用户输入当成永远正确真实程序不能假设用户一定按提示输入。越靠近外部输入越要防御。十一、本章练习写一个程序输入姓名和城市输出一句自我介绍。写一个程序输入两个整数输出它们的和。写一个程序输入身高和体重计算 BMI。写一个程序输入年龄判断是否成年。要求年龄不是整数时提示错误。修改注册程序手机号必须以1开头。十二、本章总结本章你需要掌握println输出并换行。print输出不换行。printf可以格式化输出。Scanner可以读取用户输入。nextLine读取整行。nextInt、nextDouble读取指定类型但要注意输入不匹配。nextInt和nextLine混用会有换行残留问题。命令行参数适合启动时传入Scanner 适合运行中交互。外部输入必须先校验再使用。学完这一章程序已经可以和用户互动了。下一章会讲条件判断把输入数据转成不同的业务分支。