Java 方法

本文最后更新于:2024年3月18日 凌晨

Java 方法

方法是类的行为属性,标志了类所具有的功能和操作,方法由方法头和方法体组成,方法头定义方法的访问特征,方法体实现方法的功能,其一般格式如下:

1
2
3
4
修饰符1 修饰符2 ... 返回值类型 >方法名(形式参数表)[throw异常列表]
{
方法体各语句;
}

说明

  • 任何方法定义中均含有小括号(),无参方法在小括号中不含任何内容。
  • 修饰符包括方法的访问修饰符(如public等),抽象方法修饰符abstract,类方法修饰符static,最终方法修饰符final,同步方法修饰符synchronized,本地方法修饰符native
  • 形式参数规定了方法需要多少参数,每个参数的类型信息,在方法体内通过访问参数名可获取参数值,形式参数列表的格式如下:
1
类型1 参数名1,类型2 参数名2,...
  • 返回值是方法在操作完成后返回调用它的环境的数据,返回值的类型用各种类型关键字(如,int,float等)来指定,如果方法无返回值,则用void标识。
  • 对于有返回值的方法,在方法体中一定要有一条return语句,该语句的形式有以下两种:
    • "return表达式;"方法返回结果为表达式的值。
    • "return;"用于无返回值的方法退出。
  • return语句的作用是结束方法的运行,并将结果返回给方法调用者,return返回值必须与方法头定义的返回类型相匹配。

方法调用

调用方法就是要执行方法,方法调用的形式为:

1
>方法名(实际参数表)

说明

  • 实际参数表列出传递给方法的实际参数,实际参数也简称实参,它可以是常量,变量或表达式,相邻的两个实参间用逗号分隔,实参的个数,类型,顺序要与形参一致。
  • 方法调用的执行过程是,首先将实参的值传递给形参,然后执行方法体,方法运行结束,方法结果返回给调用者,然后继续执行方法调用处的后续语句。

[例4-4]:编写编写求阶乘的方法,并利用求阶乘的方法实现一个求组合的方法。

n个元素中取m个的组合计算公式为:c(n,m)=n!/((n-m)!*m!),并利用求组合的方式输出杨辉三角形。

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
public class Ex4_4 {
// 求n!的方法fac(n)
public static long fac(int n) {
long res = 1;
for (int k = 2; k <= n; k++)
res = res * k;
return res;
}
// 求n个中取m个组合方法。
public static long com(int n, int m) {
return fac(n) / (fac(n - m) * fac(m));
}
public static void main(String[] args) {
for (int n = 0; n <= 10; n++) {
for (int m = 0; m <= n; m++)
System.out.print(com(n, m) + " ");
System.out.println();
}
}
}

1
1 1
1 2 1
1 3 3 1

说明

第3~8行定义了求n!的方法fac(n),第11~13行定义了求组合的方法com(n,m),它利用求阶乘方法fac()计算组合,在main()方法中通过一个二重循环来调用求组合的方法输出杨辉三角形的各个位置的数据。

参数传递

在Java中,参数传递时以传值的方式进行的,即将实参的存储值传递给形参,这时要注意以下两种情形:

  • 对于基本数据类型的参数,其对应的内存单元存放的时变量的值,因此,它是将实参传递给形参单元,这种情况下,对形参和实参的访问操纵的是不同的内存单元,因此,在方法内对形参数据的任何修改不会影响实参。
  • 对于引用类型(如对象,数组等)的参数变量,实参和形参单元中存放的是引用地址,参数传递是是将实参存放的引用类型的引用地址传递给形参,这样,实参和形参引用的是同一对象或同一数组,因此,对形参所引用对象成员或数组元素的改变将直接影响实参对象或数组。

[例4-5]:参数传递演示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Ex4_5 {
static void paraPass(int x, int y[]) {
x = x + 1;
y[1] = y[1] + 1;
System.out.println("x=" + x);
}

public static void main(String[] args) {
int m = 5;
int a[] = {1, 4, 6, 3};
paraPass(m, a);
System.out.println("m=" + m);
for (int k = 0; k < a.length; k++)
System.out.println(a[k] + "\t");
}
}

x=6
m=5
1 5 6 3

说明

paraPass()方法有两个参数,参数x是基本类型,参数y为一维数组,也就是引用类型,方法调用时,两个实际参数分别为整型变量m和整型数组a

  • 实参m的值传递给为形参变量x分配的单元中,这样x的值为5,在paraPass()方法内将x值增加1,输出x的结果为6,方法paraPass()执行结束后,返回main()方法中,输出m的值是5
  • 第2个参数是数组,实参a中存储的是数组的引用地址,参数传递时是将实参数组a中引用地址传递给形参y,也即形参y和实参a代表同一数组,所以,当在方法内将y[1]加上1变为5后,a[1]也为5

递归

递归是方法调用中的一种特殊现象,它是在方法自身内又调用方法自己,注意,在方法内递归调用自己通常是有条件的,在某个条件下不在递归,递归调用的一个典型例子是求阶乘问题,根据阶乘的计算特点,可以发现如下规律:

1
n! = n*(n-1)!

也就是说,求5的阶乘可以将5乘上4的阶乘,而4的阶乘又是将4乘上3的阶乘,依次类推,最后1的阶乘乘为1,或0的阶乘为1,结束递归。

用数学表示形式来描述可以写成:

1
2
fac(n) = 1;// 当n=1
fac(n) = n * fac(n-1);// 当n>1

可以利用递归编写如下求阶乘的方法:

1
2
3
4
5
6
static int fac(int n) {
if (n == 1)
return 1;
else
return n*fac(n-1);
}

在编写递归方法时一定要先安排不在递归的条件检查,从而避免无限递归,递归的执行要用到堆栈来保存数据就,它在递归的过程中需要保存程序执行的线程,然后在递归结束时再逐级返回结果,返回时知道1!就可以得到2!,知道2!就可得到3!,依次类推,也就是计算递归时分为递推和回归两个阶段,采用递归计算再效率上明显不高,因此一般情况下不采用递归计算。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!