• 方法是一种语法结构,它可以把一段代码封装成一个功能,以方便重复调用。

    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) {

    }

    public static int sum(int a, int b){
    int c = a + b;
    return c;
    }
  • 使用方法的好处是?提高了代码的复用性。让程序的逻辑更清晰。

    1
    2
    3
    4
    public static int sum(int a, int b){
    int c = a + b;
    return c;
    }
  • 关于方法需要学会什么?

    1. 方法有很多不同形式的写法,同学们需要掌握在不同的业务场景下写出合适的方法形式
    2. 方法定义出来是拿来调用的,只能调用才能让方法跑起来
    3. 方法在内存中具体是怎么去工作的
    4. 方法的参数传递原理是什么样的,需要注意什么问题
    5. 如方法在开发中常见的开发形式:方法重载、方法递归

方法定义、调用

方法完整的定义形式、调用

  • 方法定义的完整格式:

    1
    2
    3
    4
    修饰符 返回值类型 方法名( 形参列表 ){
    方法体代码(需要执行的功能代码)
    return 返回值;
    }
  • 示例:使用方法对2个整数求和并返回

    1
    2
    3
    4
    public static int add ( int a , int b ){
    int c = a + b;
    return c;
    }
  • 方法必须调用才可以跑起来,调用格式:方法名(…);

    1
    2
    int sum = add(10, 20);
    System.out.println(sum);
  • 方法的调用流程 - Debug

    • 只点击Step Over只能在main方法中一步步执行,想要进入方法需要点击Step Into

      2022-106 (1)
      2022-106 (2)

  • 方法格式的注意点

    1. 方法的修饰符:暂时都使用 public static 修饰。
    2. 方法申明了具体的返回值类型,内部必须使用return返回对应类型的数据。
    3. 形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package study;

/**
* 方法完整的定义形式、调用
*/
public class Demo01 {
public static void main(String[] args) {
System.out.println("开始");

int sum = add(10, 20);
System.out.println(sum);

System.out.println("结束");
}

public static int add(int a, int b){
int c = a + b;
return c;
}
}

方法的其他定义形式、调用

  • 方法定义时:返回值类型、形参列表可以按照需求进行填写

    1
    2
    3
    4
    修饰符  返回值类型  方法名(形参列表){
    方法体代码(需要执行的功能代码)
    return 返回值;
    }
  • 示例

    1
    2
    3
    4
    5
    6
    //  打印3行Hello World(使用方法)
    public static void print(){
    System.out.println("Hello World");
    System.out.println("Hello World");
    System.out.println("Hello World");
    }
  • 注意事项

    • 如果方法不需要返回结果,返回值类型必须申明成void(无返回值)。
    • 方法没有申明返回值类型,内部不能使用return返回数据。
    • 如果方法不需要参数,则形参列表可以不写。
    • 方法如果没有形参列表,调用的时候则不能传入参数值,否则报错。
    • 方法如果没有参数,或者返回值类型申明为void,可以称为无参数、无返回值的方法,依次类推。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package study;

/**
* 方法的其他定义形式、调用
*/
public class Demo02 {
public static void main(String[] args) {
print();
}

public static void print(){
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
}
}

方法使用的常见问题

  • 方法的编写顺序无所谓,定义的函数必须放在主函数外面,前后皆可。
  • 方法与方法之间是平级关系,不能嵌套定义。
  • 方法的返回值类型为void(无返回值),方法内则不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。
  • return语句下面,不能编写代码,因为永远执行不到,属于无效的代码。
  • 方法不调用就不执行, 调用时必须严格匹配方法的参数情况。
  • 有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用

方法案例

定义方法的技巧

  • 修饰符:public static (暂时固定的)
  • 返回值类型到底写什么是需要分析的。
  • 方法名称:自己取名,有意义,英文小写,驼峰模式。(有意义的名字即可
  • 形参列表到底写什么也是需要分析的。
  • 方法体代码:完成自己需要写的功能代码即可。
  • 快捷键:选中要抽成方法的代码块,Ctrl + Alt + M

结论:定义方法时真正需要关注的就两点:1、分析方法是否需要申明返回值类型;2、分析方法是否需要接收参数

计算返回1至n的和

  • 需求:定义一个方法,方法中计算出1~n的和并返回。

  • 分析:

    1. 根据格式编写方法:因n不固定,故方法需要声明形参接收;要返回结果,还需申明返回值类型
    2. 方法内部使用 for 循环计算出 1~n 的和并返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package study;

/**
* 计算返回1~n的和
*/
public class Demo03 {
public static void main(String[] args) {
System.out.println("1~5的和是:" + sum(5));
System.out.println("1~10的和是:" + sum(10));
}

public static int sum(int n) {
// 累加求和
int sum = 0;
for (int i = 1; i <= n; i++) {
sum+= i;
}
return sum;
}
}

判断整数是奇数还是偶数

  • 需求:拿一个整数,然后调用方法,把整数交给方法,在方法中输出该数为奇数还是偶数

  • 分析:

    1. 根据格式编写方法:因要传入数据给方法,方法需要声明形参接收
    2. 方法内部使用if语句判断,并输出对应的结论。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package study;

/**
* 判断整数是奇数还是偶数
*/
public class Demo04 {
public static void main(String[] args) {
odevity(10);
odevity(7);
}

public static void odevity(int number) {
if (number % 2 == 0) {
System.out.println(number + "是偶数");
} else {
System.out.println(number + "是奇数");
}
}
}

数组求最值案例改方法实现

  • 需求:把找出数组的最大值案例,改造成方法,可以支持返回任意整型数组的最大值数据。

  • 分析:

    1. 根据格式编写方法
    2. 要返回最大值,需要申明返回值类型
    3. 需要接收数组,需要申明形参列表
    4. 方法内部找出数组的最大值并返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package study;

/**
* 数组求最值案例改方法实现
*/
public class Demo05 {
public static void main(String[] args) {
int[] arr = {11, 23, 45, 74, 98, 126};
System.out.println("数组的和为:" + arrSum(arr));
System.out.println("数组的最小值为:" + arrMin(arr));
System.out.println("数组的最大值为:" + arrMax(arr));
System.out.println("去掉最小和最大,取平均值(不考虑小数部分):" + arrAverage(arr));
}

// 数组求和
public static int arrSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}

// 数组求最小值
public static int arrMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
min = min < arr[i] ? min : arr[i];
}
return min;
}

// 数组求最大值
public static int arrMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
max = max > arr[i] ? max : arr[i];
}
return max;
}

// 去掉最小和最大,取平均值(不考虑小数部分)
public static int arrAverage(int[] arr) {
int sum = arrSum(arr);
int min = arrMin(arr);
int max = arrMax(arr);
int average = (sum - (min + max)) / (arr.length - 2);
return average;
}
}

方法调用的内存图

  • 方法是放在方法区中的,被调用的时候,需要进入到栈内存中运行

    2022-106 (3)
    2022-106 (4)


方法的参数传递机制

基本类型的参数传递

  • Java的参数传递机制:值传递
    在传输实参给方法的形参的时候,并不是传输实参变量本身,而是传输实参中存储的值,这就是值传递

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Test {
    public static void main(String[] args) {
    int a = 10;
    int b = 20;
    change(a);
    }
    public static void change(int c){
    }
    }
  • 注意:

    1. 实参:如在方法内部定义的变量。
    2. 形参:如在定义方法时,“()”中所声明的参数。
  • 基本类型的参数传递-图解

    2022-106 (5)

引用类型的参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
int[] arrs = new int[]{10, 20, 30};
change(arrs);
System.out.println(arrs[1]); // 222
}

public static void change(int[] arrs){
System.out.println("方法内部2:"+arrs[1]); // 20
arrs[1] = 222;
System.out.println("方法内部2:"+arrs[1]); // 222
}
}
  • 引用类型的参数传递-图解

    2022-106 (6)

  • 基本类型和引用类型的参数在传递的时候有什么不同?

    1. 都是值传递。
    2. 基本类型的参数传输存储的数据值,所做的修改只在方法内部有效
    3. 引用类型的参数传输存储的地址值,所做的修改可以影响到原数据

方法的参数传递案例

打印数组内容

  • 需求:设计一个方法用于输出任意整型数组的内容,要求输出成如下格式:
    “该数组内容为:[11, 22, 33, 44, 55]”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package study;

/**
* 打印数组内容
*/
public class Demo06 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
arrPrint(arr);
}

public static void arrPrint(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.print(arr[i]);
} else {
System.out.print(arr[i] + ",");
}
}
System.out.print("]");
}
}

从数组中查询元素的索引返回

  • 需求:设计一个方法可以接收整型数组,和要查询的元素值;最终要返回元素在该数组中的索引,如果数组中不存在该元素则返回 -1。

    1
    2
    3
    例如: [11, 22, 33, 44, 55]
    输入元素:44。返回索引3
    输入元素:88。返回-1
  • 分析:

    1. 是否需要返回值类型?是否需要参数申明?
    2. 定义数组,并指定要搜索的元素值,调用方法得到返回的结果输出即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package study;

import java.util.Scanner;

/**
* 从数组中查询元素的索引返回
*/
public class Demo07 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
Scanner scanner = new Scanner(System.in);
System.out.println("你要找谁?我告诉你它在哪:");
int a = scanner.nextInt();
int res = arrFind(arr, a);
if (res == -1) {
System.out.println("不存在该客户");
} else {
System.out.println("在" + res + "号房间");
}
}

private static int arrFind(int[] arr, int a) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == a) {
index = i;
}
}
return index;
}
}

比较两个数组内容是否相等

  • 需求:如果两个数组的类型,元素个数,元素顺序和内容是一样的我们就认为这2个数组是一模一样的。请使用方法完成:能够判断任意两个整型数组是否一样,并返回true或者false。

  • 分析:

    1. 定义方法: 是否需要返回值类型?是否需要申明参数?
    2. 在方法内部完成判断的逻辑,并返回布尔结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package study;

/**
* 比较两个数组内容是否相等
*/
public class Demo08 {
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5,6};
int[] arr2 = {1,2,3,4,5,6};
int[] arr3 = {1,2,5,4,5,6};

boolean res1 = arrSame(arr1, arr2);
if (res1 == true) {
System.out.println("数组arr1与arr2相同。");
} else {
System.out.println("数组arr1与arr2不相同!");
}

boolean res2 = arrSame(arr1, arr3);
if (res2 == true) {
System.out.println("数组arr1与arr3相同。");
} else {
System.out.println("数组arr1与arr3不相同!");
}
}

public static boolean arrSame(int[] arr1, int[] arr2) {
if (arr1.length != arr2.length) {
return false;
} else {
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
}
return true;
}
}

方法重载

方法重载的形式、作用

  • 同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法

    2022-106 (7)

  • 方法重载的作用:可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。

  • 方法重载是什么样的?
    同一个类中,多个方法的名称相同,形参列表不同。通过参数的不同来区分调用的是哪个方法

  • 使用方法重载的好处 ?
    对于相似功能的业务场景:可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。

方法重载的识别技巧

  • 只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓)

  • 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package study;

/**
* 方法重载
*/
public class Demo09 {
public static void main(String[] args) {

}

// 1,方法fire
public static void fire() {
}

// 2,方法名相同,参数列表不同,属于方法重载
public static void fire(int num) {
}

// 3,Java大小写敏感,与fire不是同一个方法,不能叫方法重载
public static void FIRE(int num) {
}

// 4,方法名相同,参数列表不同,属于方法重载
public static void fire(int num, int b) {
}
}

补充知识:单独使用return关键字

  • return可以立即跳出并结束当前方法的执行。

  • 如果要直接结束当前方法的执行,怎么解决?

    1. return; 跳出并立即结束所在方法的执行。
    2. break; 跳出并结束当前所在循环的执行。
    3. continue; 结束当前所在循环的当次继续,进入下一次执行。