Java 基础入门(五):控制台输入输出与方法详解

发布时间:2026/11/2 1:22:00
Java 基础入门(五):控制台输入输出与方法详解

文章目录

    • 一、控制台输出
      • 1.1 常见的输出方法
        • 1.1.1 println():输出并换行
        • 1.1.2 print():输出但不换行
        • 1.1.3 printf():格式化输出
    • 二、控制台输入
      • 2.1 Scanner 的基本使用
      • 2.2 输入字符串
        • 2.2.1 next():读取一个单词
        • 2.2.2 nextLine():读取一整行
        • 2.2.3 next() 与 nextLine() 的区别
      • 2.3 输入整数
      • 2.4 输入浮点数
      • 2.5 Scanner 常用输入方法总结
      • 2.6 如何处理多组输入?
    • 三、方法的概念与使用
      • 3.1 方法的概念
      • 3.2 方法的定义
      • 3.3 方法的定义与调用
      • 3.4 方法的返回值
        • 3.4.1 有返回值的方法
        • 3.4.2 没有返回值的方法
      • 3.5 方法的参数
      • 3.6 形参和实参
      • 3.7 Java 的参数传递:值传递
        • 3.7.1 为什么 swap() 不能交换两个 int 变量?
        • 3.7.2 结合方法调用栈理解
    • 四、方法重载
      • 4.1 方法重载的概念
      • 4.2 方法重载示例
      • 4.3 重载方法如何匹配?

一、控制台输出

在 Java 中,控制台输出是指将程序运行过程中产生的信息显示在控制台上。

前面的学习中,我们已经多次使用:

System.out.println();

实际上,Java 还提供了其他常见的输出方式。

1.1 常见的输出方法

Java 中常见的控制台输出方法包括:

方法作用
System.out.print()输出内容,不自动换行
System.out.println()输出内容,结束后换行
System.out.printf()按照指定格式输出内容
1.1.1 println():输出并换行
publicclassOutputDemo{publicstaticvoidmain(String[]args){System.out.println("Hello");System.out.println("Java");}}

运行结果:

Hello Java

println()在输出指定内容后,会自动换行。

因此,下一次输出会从新的一行开始。

1.1.2 print():输出但不换行
publicclassOutputDemo{publicstaticvoidmain(String[]args){System.out.print("Hello ");System.out.print("Java");}}

运行结果:

Hello Java

print()不会自动换行,因此后续内容会继续输出在同一行。

如果希望主动换行,可以使用转义字符\n。

例如:

System.out.print("Hello\nJava");

运行结果:

Hello Java
1.1.3 printf():格式化输出

printf()允许在字符串中使用格式说明符,按照指定格式输出数据。

例如:

publicclassOutputDemo{publicstaticvoidmain(String[]args){Stringname="Tom";intage=20;doublescore=95.678;System.out.printf("姓名:%s,年龄:%d,成绩:%.2f%n",name,age,score);}}

运行结果:

姓名:Tom,年龄:20,成绩:95.68

常见的格式说明符:

格式说明符作用示例
%d输出十进制整数20
%f输出浮点数3.140000
%.2f保留两位小数3.14
%s输出字符串形式的内容Hello
%c输出字符A
%b输出布尔形式的内容true

二、控制台输入

前面编写的程序中,大部分数据都是直接写在代码中的。

例如:

intage=20;

但实际开发中,数据往往需要由用户输入。

为了在 Java 程序中读取控制台输入,可以使用Scanner类。

2.1 Scanner 的基本使用

Scanner位于java.util包中,因此使用之前需要导入:

importjava.util.Scanner;

随后创建Scanner对象:

Scannerscanner=newScanner(System.in);

其中:

  • Scanner:Java 提供的输入扫描类。
  • scanner:创建的对象名称。
  • new Scanner(System.in):创建一个从标准输入读取数据的 Scanner 对象。
  • System.in:Java 的标准输入流,通常对应控制台输入。

现在还没有正式学习类和对象,因此暂时只需要掌握这段代码的基本用法即可。

2.2 输入字符串

使用Scanner输入字符串时,常见的两个方法是:

next()nextLine()

虽然它们都能读取字符串,但读取规则不同。

2.2.1 next():读取一个单词

next()会读取下一个以空白字符分隔的输入内容。

这里的空白字符通常包括:

  • 空格
  • 制表符
  • 换行符

示例:

importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.print("请输入姓名:");Stringname=scanner.next();System.out.println("姓名:"+name);}}

假设输入:

Zhang San

程序输出:

姓名:Zhang

这是因为next()遇到空格后,当前内容读取结束。

2.2.2 nextLine():读取一整行

如果希望读取包含空格的完整内容,可以使用nextLine()。

importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.print("请输入姓名:");Stringname=scanner.nextLine();System.out.println("姓名:"+name);}}

假设输入:

Zhang San

程序输出:

姓名:Zhang San

nextLine()会读取当前行剩余的内容,直到遇到行结束位置,并且不会将换行符包含在返回的字符串中。

2.2.3 next() 与 nextLine() 的区别
比较项next()nextLine()
读取单位一个以空白分隔的内容当前行剩余内容
能否读取带空格的完整句子不适合可以
遇到空格当前内容结束继续读取
遇到换行作为分隔符结束当前行

注意:混合使用 nextInt() 与 nextLine() 时,需要特别小心。

例如:

Scannerscanner=newScanner(System.in);System.out.print("请输入年龄:");intage=scanner.nextInt();System.out.print("请输入姓名:");Stringname=scanner.nextLine();

假设用户输入年龄20后按下回车。

此时nextInt()只读取整数,当前行末尾的换行仍然留在输入中。

紧接着执行nextLine(),它会读取当前行剩余的内容,因此可能直接得到一个空字符串。

如果希望接下来输入新的一行,可以先读取掉当前行的剩余内容:

intage=scanner.nextInt();scanner.nextLine();// 消耗当前行剩余内容Stringname=scanner.nextLine();

这是Scanner使用过程中非常常见的易错点。

2.3 输入整数

如果希望用户输入整数,可以使用:

nextInt()

例如:

importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.print("请输入年龄:");intage=scanner.nextInt();System.out.println("年龄:"+age);}}

示例运行:

请输入年龄:20 年龄:20

需要注意,nextInt()要求下一个输入内容能够按照相应的整数格式解析。

如果输入的是无法解析为整数的内容,例如abc,就可能抛出InputMismatchException。

2.4 输入浮点数

如果希望读取小数,可以根据需要使用:

nextFloat()nextDouble()

例如:

importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.print("请输入体重:");doubleweight=scanner.nextDouble();System.out.println("体重:"+weight);}}

示例运行:

请输入体重:65.5 体重:65.5

其中:

  • nextFloat():读取float类型的数据。
  • nextDouble():读取double类型的数据。

2.5 Scanner 常用输入方法总结

方法作用
next()读取下一个字符串内容
nextLine()读取当前行剩余内容
nextInt()读取 int 整数
nextFloat()读取 float 浮点数
nextDouble()读取 double 浮点数

这些方法的输入格式应当与预期的数据类型一致,否则可能出现输入异常。

2.6 如何处理多组输入?

在算法练习中,经常需要连续读取多个整数,但题目不一定提前告知输入数据的数量。

这时,可以结合while循环和Scanner的hasNextInt()方法实现。

例如:

importjava.util.Scanner;publicclassInputDemo{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);while(scanner.hasNextInt()){intnum=scanner.nextInt();System.out.println(num);}}}

运行过程:

程序启动后,等待用户输入整数。

10 // 用户输入 10,按下回车 10 // 程序输出 10 20 // 用户输入 20,按下回车 20 // 程序输出 20 30 // 用户输入 30,按下回车 30 // 程序输出 30

注意:

  • hasNextInt()用于判断下一个输入内容能否解析为int,本身不会消耗该整数。
  • nextInt()用于实际读取整数。
  • 输入三个整数后,程序不会自动结束,而是继续等待后续输入。
  • 如果需要主动结束输入,可以向控制台发送文件结束标记(EOF)。Windows 命令行通常使用Ctrl + Z后按回车;Linux、macOS 终端通常使用Ctrl + D。IDEA 中的操作可能因控制台配置而不同。

此外,也可以一次性输入10 20 30,因为nextInt()会按照空白字符分隔读取每个整数。但在学习阶段,逐个输入更有助于理解循环读取的执行过程。

三、方法的概念与使用

在前面的学习中,我们已经能够使用流程控制解决一些问题。

例如,判断某一年是否为闰年:

intyear=2024;if((year%4==0&&year%100!=0)||year%400==0){System.out.println("是闰年");}else{System.out.println("不是闰年");}

如果程序中有多个位置都需要判断闰年,难道每次都需要重新编写这段代码吗?

显然没有必要。

这时,就可以使用方法(Method),将具有特定功能的代码组织起来,方便重复调用。

3.1 方法的概念

方法是 Java 中用于完成特定功能的一段代码。

通过方法,我们可以将复杂的程序拆分为多个功能相对独立的部分。

使用方法具有以下好处:

  • 提高代码复用性:相同功能不需要重复编写。
  • 提高代码可读性:通过方法名称表达功能。
  • 降低维护成本:修改某个功能时,可以集中修改对应方法。
  • 便于分解问题:将复杂问题拆分为多个简单任务。

3.2 方法的定义

在当前基础阶段,可以先掌握以下常见写法:

publicstatic返回值类型 方法名(参数列表){// 方法体return返回值;}

其中:

组成部分含义
public访问修饰符
static静态修饰符
返回值类型表示方法返回结果的类型
方法名用于标识并调用方法
参数列表用于接收调用方法时传入的数据
方法体方法实际执行的代码
return结束当前方法,可同时返回结果

这里的public和static涉及后续的面向对象知识。

现阶段可以先理解为:使用static定义的静态方法,可以在同一个类的静态main方法中直接通过方法名调用。

3.3 方法的定义与调用

以判断闰年为例。

我们可以将判断逻辑封装成一个方法:

publicclassMethodDemo{// 判断一个年份是否为闰年publicstaticbooleanisLeapYear(intyear){return(year%4==0&&year%100!=0)||year%400==0;}publicstaticvoidmain(String[]args){intyear=2024;booleanresult=isLeapYear(year);if(result){System.out.println("是闰年");}else{System.out.println("不是闰年");}}}

运行结果:

是闰年

3.4 方法的返回值

方法可以有返回值,也可以没有返回值。

3.4.1 有返回值的方法

例如,计算两个整数之和:

publicstaticintadd(inta,intb){returna+b;}

调用:

intresult=add(10,20);System.out.println(result);// 30

这里的int表示方法返回一个整数结果。

return a + b;会将计算结果返回给调用方,并结束当前方法。

3.4.2 没有返回值的方法

如果方法只负责输出信息,不需要向调用者返回结果,可以使用void。

例如:

publicstaticvoidhello(){System.out.println("Hello Java");}

调用:

hello();

运行结果:

Hello Java

注意:

  • 有返回值的方法,需要保证正常完成的执行路径符合返回值要求。
  • void方法不返回结果,但可以使用单独的return;提前结束方法。
  • 方法的返回类型需要与实际返回的表达式在 Java 类型规则下兼容。

3.5 方法的参数

方法可以通过参数接收外部传入的数据。

例如:

publicstaticintadd(inta,intb){returna+b;}

这里的a、b就是方法定义中的参数。

调用时:

add(10,20);

向方法传入了两个实际数值。

这就涉及两个重要概念:形参和实参。

3.6 形参和实参

形参(Formal Parameter)

形参是方法定义时声明的参数,用于接收调用方传入的数据。

例如:

publicstaticintadd(inta,intb)

这里的:

a、b

就是形参。

实参(Actual Argument)

实参是调用方法时提供的实际参数值或表达式。

例如:

add(10,20);

这里的:

10、20

就是实参。

方法调用时,需要满足相应的参数匹配规则,包括参数数量、类型兼容性以及参数顺序等。

对于普通的位置参数调用,实参与形参按位置对应。

例如:

publicstaticvoidprintInfo(Stringname,intage){System.out.println(name+":"+age);}

正确调用:

printInfo("Tom",20);

不能直接将两种不同类型的参数顺序颠倒:

// printInfo(20, "Tom"); // 编译错误

3.7 Java 的参数传递:值传递

Java 的方法参数传递采用值传递(Pass by Value)。

所谓值传递,就是调用方法时,将实参表达式计算得到的值复制一份,用于初始化形参。

对于基本数据类型,形参与调用方的变量相互独立,修改形参不会影响调用方变量的值。

3.7.1 为什么 swap() 不能交换两个 int 变量?

先观察下面的代码:

publicclassTest{publicstaticvoidswap(intx,inty){inttemp=x;x=y;y=temp;}publicstaticvoidmain(String[]args){inta=10;intb=20;swap(a,b);System.out.println("a = "+a);System.out.println("b = "+b);}}

运行结果:

a = 10 b = 20

明明在swap()中执行了交换操作,为什么a和b的值没有改变?

3.7.2 结合方法调用栈理解

Java 中,每次方法调用都会创建对应的栈帧(Stack Frame),用于保存本次调用的局部变量及其他执行状态。

① 调用 swap() 前

此时只有main()方法的栈帧:

栈顶 ┌─────────────────┐ │ main() │ │ a = 10 │ │ b = 20 │ └─────────────────┘ 栈底

② 调用 swap(a, b)

执行swap(a, b)时,会创建新的栈帧,并将a、b的值分别复制给形参x、y。

栈顶 ┌─────────────────┐ │ swap() │ │ x = 10 │ │ y = 20 │ ├─────────────────┤ │ main() │ │ a = 10 │ │ b = 20 │ └─────────────────┘ 栈底

注意:x、y与a、b是不同的局部变量。

③ swap() 内部完成交换

inttemp=x;x=y;y=temp;

此时:

栈顶 ┌─────────────────┐ │ swap() │ │ x = 20 │ │ y = 10 │ │ temp = 10 │ ├─────────────────┤ │ main() │ │ a = 10 │ │ b = 20 │ └─────────────────┘ 栈底

可以发现,交换的只是swap()中的形参,main()中的变量并未改变。

④ swap() 执行结束

swap()对应的栈帧退出,程序返回main()继续执行。

因此,最终输出仍然是:

a = 10 b = 20

以上栈帧图仅用于说明方法调用和局部变量之间的关系,并非 JVM 的完整内存结构。

四、方法重载

在实际开发中,有时多个方法完成的功能相似,但需要处理的参数不同。

例如:

  • 计算两个整数之和。
  • 计算三个整数之和。
  • 计算两个浮点数之和。

如果每个方法都使用不同名称,可能降低代码的统一性。

Java 提供了方法重载(Method Overloading)来解决这类问题。

4.1 方法重载的概念

方法重载是指在同一个类中,允许定义多个名称相同、但参数列表不同的方法。

构成方法重载需要满足:

  1. 方法名称相同。
  2. 参数列表不同。

其中,参数列表不同可以体现为:

  • 参数数量不同。
  • 参数类型不同。
  • 参数类型的排列顺序不同。

注意:方法的返回值类型不能单独作为判断重载的依据。

4.2 方法重载示例

publicclassOverloadDemo{// 两个整数相加publicstaticintadd(inta,intb){returna+b;}// 三个整数相加publicstaticintadd(inta,intb,intc){returna+b+c;}// 两个 double 类型数据相加publicstaticdoubleadd(doublea,doubleb){returna+b;}publicstaticvoidmain(String[]args){System.out.println(add(10,20));System.out.println(add(10,20,30));System.out.println(add(1.5,2.5));}}

运行结果:

30 60 4.0

虽然三个方法都叫add,但参数列表不同,因此可以构成方法重载。

4.3 重载方法如何匹配?

在调用重载方法时,Java 编译器会根据方法名称和实际参数,按照方法调用的匹配规则选择合适的方法。

例如:

add(10,20);

两个参数都是int,因此可以匹配:

add(inta,intb)

如果调用:

add(1.5,2.5);

则可以匹配:

add(doublea,doubleb)

下一篇文章将介绍Java 程序调试(Debug),重点讲解 IntelliJ IDEA 中断点的设置、Debug 模式的使用、单步执行、变量值的观察以及方法调用过程的跟踪,帮助读者掌握程序调试的基本方法,学会分析代码执行流程、定位错误,并进一步加深对方法调用和递归执行过程的理解。