欢迎光临
我们一直在努力

Java输入输出与方法

目录

一. 从键盘输出

二. 从键盘输入

处理多组输入

三. 方法

3.1 方法的书写方式

3.2 方法调用

3.3 形参和实参的关系

3.4 方法重载

3.4.1 方法签名

3.5 方法递归

3.5.1 理解递归代码执行逻辑

四. 总结


一. 从键盘输出

使用println将内容输出到控制台

System.out.println("要输出到控制台的内容");

println输出自带\\n这个换行符,如果不想要这个换行符,可以用print

printf是格式化输出,其写法与C语言的printf是一样的,不多介绍

二. 从键盘输入

使用Scanner类来读取键盘输入的内容

//使用Scanner时需要先导包
import java.util.Scanner;

Scanner sc = new Scanner(System.in);
String s = sc.next();
int age = sc.nextInt();
String t =sc.nextLine();
double d = sc.nextDouble();
sc.close();
//使用完后需要调用方法关闭

next系列方法都是从键盘接收数据,这些方法的结束标志都是换行符\\n,也就是键盘上的回车,从键盘中接收输入的内容,读到回车后结束。且这几个方法都不会读到最后的\\n

所以在使用的时候,需要特别注意一个情况:

Scanner sc = new Scanner(System.in);
int age = scanner.nextInt();
String name = scanner.nextLine();
System.out.println(name);

由于nextInt()是读取到键盘输入\\n回车时结束,但nextLine()意思是读取一行,会读取到这个\\n,\\n正好是结束的标识符,所以实际使用的时候,如果前面用了nextInt(),我们需要单独的再写一个nextLine(),来专门读取这个回车,以免后续程序出现问题

Scanner sc = new Scanner(System.in);
int age = sc.nextInt();
sc.nextLine();
String name = sc.nextLine();
System.out.println(name);

处理多组输入

示例:使用 Scanner 循环读取 N 个数字,并求取其平均值

Scanner sc = new Scanner(System.in);
int sum = 0;
int num = 0;
while (sc.hasNextInt()) {
int tmp = sc.nextInt();
sum += tmp;
num++;
}
System.out.println("sum = " + sum);
System.out.println("avg = " + sum / num);
sc.close();

Scanner.hasNext()方法是用于检查扫描器的输入中是否还有下一个输入,如果有则返回true,否则会持续等待用户输入,并不会返回false。

在Windows中,我们可以按键盘上的ctrl+z来直接终止输入(Linux用ctrl+d)

为了避免无限等待用户输入,我们也可以使用带参数的hasNext()方法,此时如果你输入的内容与参数值一样,此时就会返回true

Scanner sc = new Scanner(System.in);
while(!sc.hasNext("#")) { // 以#为结束符号
System.out.println("键盘输入的内容是:" + sc.next());
}
System.out.println("会执行的");

此时用户输入#时,循环就会结果,继续执行后面代码

三. 方法

方法就是一个代码片段,类似C语言的函数,方法的意义在于:

  • 当代码比较复杂的时候,可以模块化的组织代码
  • 能够做到让代码被重复使用,而不用反复写多次相同逻辑
  • 使得代码更加简洁,容易理解
  • 可以让我们直接基于现有方法开发
  • 3.1 方法的书写方式

    语法:

    // 方法定义
    修饰符 返回值类型 方法名称([参数类型 形参 …]){
    方法体代码;
    [return 返回值];
    }

    示例:写一个实现求两数之和的方法

    public class Test{
    //方法的定义
    public static int add(int x, int y) {
    return x + y;
    }
    }

    简单介绍:

  • 上面的public和static都是方法的修饰限定符,决定方法类型,但不影响方法本身逻辑
  • 修饰符后面跟着的是返回类型,可以是基本数据类型或引用类型,也可以是void,表示没有返回值,这部分影响方法体中return后面跟的类型
  • 方法名用于标识方法,在后面使用方法的时候会用到
  • 参数列表表示该方法可以接受的参数有哪些,参数的格式一般为类型+变量名,表示可以这个方法需要两个int类型的变量
  • 需要注意的地方:

    • Java的方法名称,一般采用小驼峰的命名方式,即第一个单词首字母小写,其余首字母大写
    • 参数列表中若没有参数,可以什么都不写,若有则参考上面,多个参数之间,隔开
    • Java中,方法必须写在类中
    • Java中,方法不能嵌套定义
    • Java中,没有方法声明一说

    3.2 方法调用

    方法写好之后,需要调用才会被执行,比如要调用上面求两数之和的方法,写法如下:

    public class Test{
    //方法的定义
    public static int add(int x, int y) {
    return x + y;
    }
    int c = add(1,2);
    }

    上面的add(1,2)就是调用方法,然后用c来接收方法的返回值

    总结:

    • 定义方法的时候, 不会执行方法的代码. 只有调用的时候才会执行.
    • 调用方法的时候,需要使用方法名+参数列表的形式进行调用
    • 如果方法有返回值,需要接收返回值结果
    • 一个方法可以被多次调用

    3.3 形参和实参的关系

    首先,方法定义时的参数列表中的参数,这就叫形参,方法调用时传递的参数,这就叫实参

    形参就相当于数学公式中的自变量,实参就相当于实际给因变量传递的值。

    形参的名字可以随意取,对方法没任何影响,形参只是方法在定义时需要借助的变量,用于保存方法在调用时传递过来的值

    特别注意:

  • 在Java中,实参的值永远都是拷贝到形参中,形参和实参本质是两个实体
  • 实参传值给形参,必须做到类型匹配,顺序匹配,个数匹配
  • 形参的作用域,仅限于方法体内部,出了方法体就会被销毁,无法使用
  • 实参的作用域与定义实参的位置有关,跟随定义实参的方法。
  • 这里牵扯到一个经典案例:交换实参的值

    public class HelloWorld {
    public static void main(String[] args) {
    int a = 10;
    int b = 20;
    System.out.println("交换前: a = " + a + " b = " + b);
    swap(a, b);
    System.out.println("交换后: a = " + a + " b = " + b);
    }
    public static void swap(int x, int y) {
    int tmp = x;
    x = y;
    y = tmp;
    }
    }
    // 运行结果
    //交换前: a = 10 b = 20
    //交换后: a = 10 b = 20

    原因在于,实参a和b是main方法里的两个变量,存储于main方法的栈中(一块特殊的内存空间),而形参x和y是swap方法中的两个变量,存储于swap方法运行时的栈中。所以:实参a和b于形参x和y是两个没有任何关联性的变量,在swap方法调用时,只是将实参a和b的值拷贝了一份,传递给了形参x和y,在swap方法中对x和y进行操作,不会对实参a和b产生任何影响。 也就是说,Java的方法,传参时永远是按值传递,而不是传递引用(变量地址)

    如果想要完成实参的交换,需要传递的是引用,可以借助后续的引用类型来完成

    3.4 方法重载

    方法重载就相当于我们的中文,一个词语有很多个含义,Java中,如果多个方法,名字相同,参数列表不同,这就叫方法重载。

    方法重载的意义在于,有时候我们想通过一个方法,同时完成多件事,比如一个计算两数之和的方法,想要同时完成整数相加和小数相加,此时由于参数列表的类型与实参类型必须匹配,就导致只能完成一件,而有了重载,这种情况就可以被很方便的解决

    public class HelloWorld {
    public static void main(String[] args) {
    add(1, 2); // 调用add(int, int)
    add(1.5, 2.5); // 调用add(double, double)
    add(1.5, 2.5, 3.5); // 调用add(double, double, double)
    }
    public static int add(int x, int y) {
    return x + y;
    }
    public static double add(double x, double y) {
    return x + y;
    }
    public static double add(double x, double y, double z) {
    return x + y + z;
    }
    }

    注意:

  • 方法名必须相同
  • 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
  • 与返回值类型是否相同无关
  • 编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法
  • 3.4.1 方法签名

    在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量,那为什么类中就可以定义方法名相同的方法呢?  因为每个方法都有不同的签名

    方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式:方法全路径名+参数列表,构成方法完整的名字。

    3.5 方法递归

    递归的概念:一个方法在执行过程中,自己调用了自己,这种行为就叫递归

    递归的必要条件:

  • 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
  • 递归出口
  • 递归的意义:

    有时候我们遇到的问题不好直接解决,但将原问题拆分为其子问题时,子问题与原问题有相同解法,把子问题解决后,原问题也就迎刃而解了。

    代码示例:递归求N的阶乘

    我们来按照上面思路拆分,n! = n * (n-1) * (n-2)…* (1)

    此时我们可以这么理解:n! = n * (n-1)!

    此时我们就发现,(n-1)!的解法与n!解法是一样的,那么递归什么时候结束?当n=1时。

    所以我们就可以写出下面代码:

    public class HelloWorld {
    public static void main(String[] args) {
    int n = 5;
    int ret = factor(n);
    System.out.println("ret = " + ret); //ret = 120
    }
    public static int factor(int n) {
    if (n == 1) {
    return 1;
    }
    return n * factor(n – 1); // factor 调用函数自身
    }
    }

    3.5.1 理解递归代码执行逻辑

    递归代码执行过程通常较难理解,想明白递归的逻辑,必须理解方法的执行过程,尤其是"方法执行结束之后,回到调用位置继续往下执行"

    上面就是递归代码执行的基本逻辑

    在方法调用时上面所画的f(4)之类,其实都是在栈上进行执行的

    关于 "调用栈"

    方法调用的时候, 会有一个 "栈" 这样的内存空间描述当前的调用关系. 称为调用栈. 每一次的方法调用就会开辟一个 "栈帧", 每个栈帧中包含了这次调用的参数是哪些, 返回到哪里继续执行等信息. 后面我们借助 IDEA 很容易看到调用栈的内容.

    四. 总结

    本文简单介绍了Java简单输入输出,以及方法相关内容,方法这部分,属于Java基础的重中之重,后续会特别经常用到方法。最后希望您看完本文能有所收获。

    赞(0)
    未经允许不得转载:171主机测评 » Java输入输出与方法
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址