目录

方法的概念及使用

什么是方法

方法的的定义

方法调用的执行过程

实参和形参的关系

没有返回值的方法

方法重载

为什么需要方法重载

方法重载的概念

方法签名

递归

递归的概念

递归执行过程分析


方法的概念及使用

什么是方法

方法其实就是一个代码片段,类似于我们C语言中的“函数”。

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

PS:

  1. 修饰符:现阶段直接使用public static 固定搭配
  2. 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成
    void
  3. 方法名字:采用小驼峰命名
  4. 参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开
  5. 方法体:方法内部要执行的语句
  6. 在java当中,方法必须写在类当中
  7. 在java当中,方法不能嵌套定义
  8. 在java当中,没有方法声明一说
方法调用的执行过程

PS:

  • 定义方法的时候, 不会执行方法的代码. 只有调用的时候才会执行.
  • 一个方法可以被多次调用.
实参和形参的关系

在数学中,我们学过自变量与因变量。

那么,在Java方法中,其实形参就相当于数学中的自变量

形参的名字可以随意取,对方法是没有影响的。因为它只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值。

public static int getSum(int N){ // N是形参
    return (1+N)*N / 2;
}
getSum(10); // 10是实参,在方法调用时,形参N用来保存10
getSum(100); // 100是实参,在方法调用时,形参N用来保存100

ps:

在Java中,实参的值永远都是拷贝到形参中的,形参和实参本质上是两个实体

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

这里可以看到,在swap函数将形参的值进行交换后,形参x和y的值发生改变了,但a和b的值还是交换之前的值。

也就是说,形参并不影响实参的值。

注意对于基础类型来说, 形参相当于实参的拷贝. 即 传值调用

没有返回值的方法

在Java中方法的返回值是可以选择的,有的时候可以没有返回值,但在没有返回值时,方法的返回值类型必须写成void。

class Test {
public static void main(String[] args) {
        int a = 10;
        int b = 20;
        print(a, b);
    }
public static void print(int x, int y) {
    System.out.println("x = " + x + " y = " + y);
    }
}
方法重载
为什么需要方法重载

当我们定义一个add方法,并设定它的参数为int类型,在我们调用add方法,并给它传double类型的参数时,就会报错。

public class TestMethod {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = add(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int add(int x, int y) {
        return x + y;
    }
}
// 编译出错
Test.java:13: 错误: 不兼容的类型: 从double转换到int可能会有损失
double ret2 = add(a2, b2);
        ^

这个原因是因为,参数类型不匹配,所以不能使用我们目前已经定义好的add方法。

此时有几种解决方法。

其中一种简单粗暴的解决方法,就是再定义一个add方法,不过这里要区分开来。

public class TestMethod {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = addInt(a, b)
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = addDouble(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int addInt(int x, int y) {
        return x + y;
    }
    public static double addDouble(double x, double y) {
        return x + y;
    }
}

这样确实能解决问题,但这样的话,我们就需要定义许多方法名,然而,这么多方法名,谁能记得住呢?我们能不能将所有的add方法都命名为add呢?

答案是可以的

方法重载的概念

这里就是方法重载的概念了,那么什么是方法重载呢

在我们日常生活中,经常会出现一词多用的情况,例如河南人的“中”,在不同的场景,会表示不同的含义。

那么,在Java中,方法可不可以“一方法多用”呢?当然可以!

在Java中,如果多个方法的名字相同,但参数列表不同,我们就说这几种方法被重载了。

public class TestMethod {
    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;
    }
}

方法重载好用是好用,但是我们要注意几点。

1.方法名必须相同

2.参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)

3.与返回值类型是否相同无关

4.编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法

// 注意:两个方法如果仅仅只是因为返回值类型不同,是不能构成重载的
public class TestMethod {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
    }
    public static int add(int x, int y) {
        return x + y;
    }
    public static double add(int x, int y) {
        return x + y;
    }
}
// 编译出错
Test.java:13: 错误: 已在类 Test中定义了方法 add(int,int)
public static double add(int x, int y) {
        ^
1 个错误
方法签名

我们之前了解到,在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量。

那为什么类中就可以定义方法名相同的方法呢?

这是因为虽然方法名是一样的,但在Java底层逻辑中,相同方法名的方法签名是不一样的

这里就涉及到一个新概念,也就是方法签名。

方法签名:经过编译器编译修改过之后方法最终的名字。

具体方式:方法全路径名+参数列表+返回值类型,构成方法完整的名字。

public class TestMethod {
    public static int add(int x, int y){
    return x + y;
    }
    public static double add(double x, double y){
        return x + y;
    }
    public static void main(String[] args) {
        add(1,2);
        add(1.5, 2.5);
    }
}

上述代码经过编译之后,然后使用JDK自带的javap反汇编工具查看,具体操作:

1.先对工程进行编译生成.class字节码文件

2.在控制台中进入到要査看的.class所在的目录

3.输入:javap -v 字节码文件名字即可

这里的方法签名中存在一些特殊符号,这些特殊符号的含义如下:

特殊字符

数据类型

V

void

Z

boolean

B

byte

C

char

S

short

I

int

J

long

F

float

D

double

[

数组(几个[表示几维数组)

L

引用类型,以L开头,;结尾,中间是引用类型的全类名

递归

递归的概念

在小时候,我们就听过一个故事。

从前有坐山,山上有座庙,庙里有个老和尚给小和尚将故事,讲的就是:

"从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事,讲的就是:

"从前有座山,山上有座庙..."

"从前有座山……"

如果老和尚一直不睡去,那么这个故事是不是一直会继续。

这便是递归的具象化。

那么,递归的具体概念是怎样呢?

一个方法在执行过程中调用自身,就称为“递归”。

递归就相当于数学中的“数学归纳法”,它有一个起始条件,也有一个递推公式

ps:

1. 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同

2. 递归出口

publicstaticvoidmain(String[]args){
    intn=5;
    intret=factor(n);
    System.out.println("ret="+ret);
    }
publicstaticintfactor(intn){
    if(n==1){
        return1;
    }
    returnn*factor(n-1); //factor调用函数自身
}
//执行结果ret=120
递归执行过程分析

递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 "方法的执行过程", 尤其是 "方法执行结束之后, 回到调用位置继续往下执行"。

public static void main(String[] args)
    int n = 5;
    int ret = factor(n);
    System.out.println("ret = " + ret);
}
public static int factor(int n) {
    System.out.println("函数开始, n = " + n);
    if (n == 1) {
        System.out.println("函数结束, n = 1 ret = 1");
        return 1;
    }
    int ret = n * factor(n - 1);
    System.out.println("函数结束, n = " + n + " ret = " + ret);
    return ret;
}
// 执行结果
函数开始, n = 5
函数开始, n = 4
函数开始, n = 3
函数开始, n = 2
函数开始, n = 1
函数结束, n = 1 ret = 1
函数结束, n = 2 ret = 2
函数结束, n = 3 ret = 6
函数结束, n = 4 ret = 24
函数结束, n = 5 ret = 120
ret = 120

上述程序按照序号中标识的(1)到(8)这样的顺序去执行。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐