2.4 方法与递归
在Java语言中,一个方法代表一个具体的逻辑功能,表达方法所属的类的对象所具有的一种行为或一种操作。递归是一种重要的程序设计技术。用递归表达程序设计逻辑十分简明。
2.4.1 方法
Java中的一个方法类似于其他语言的函数,它代表了一个具体的逻辑功能,表达了它所属的类的对象所具有的一种行为或一种操作。Java中方法定义的基本格式是:
[ 修饰符1 修饰符2…]<返回值类型><方法名>([<形式参数列表>]){ [<方法体>] }
其中:<返回值类型>可以是任何合法的Java的数据类型。若该方法没有返回值,则类型应定义为void;<方法名>是任何合法的Java标识符,Java保留字不能用做方法名。<形式参数列表>定义该方法要接收的输入值及相应类型,该列表是可以缺省的。<方法体>中是任何合法的Java语句,这些Java语句共同完成该方法所定义的逻辑功能,该部分也可以缺省。
在下面的TestMethod类中,定义了一个方法simpleMethod:
public class TestMethod { int simpleMethod(int x, int y ) { … return (x<y)?x:y; } }
在方法simpleMethod中,定义了两个形式参数x和y,返回两者之中的最小值。
2.4.2 参数传递
Java规定:所有的类型的参数传递都是“值传递”。其机制是:在方法调用运行时,首先对实在参数列表从左到右依次计算各个实在参数的值,然后在运行栈中为该方法的所有的形式参数变量分配空间,接着再为该方法体中所有其他局部变量在运行栈中分配空间,最后将已计算出来的各个实在参数的值抄送到相应的形式参数变量空间之中。这一切做完后,方法调用才开始执行方法体中的第一条语句。一旦运行完成,自动从运行栈撤销该方法的所有信息,因而该方法在运行栈中为形式参数及局部变量分配的空间也就自动撤销。
【例2.9】 打印100之间所有的质数。
PrimeNumber.java
public class PrimeNumber { boolean isPrime(int n){ // 判断是否是质数 for (int i = 2; i <= n / 2; i++) if(n % i==0) // 能被整除,则不是质数 return false; return true; } void printPrime(int m) { int j = 0; for (int i = 2; i <= m; i++){ if (isPrime(i)){ j++; if(j%10==0){ // 每10个质数一行 System.out.print(" " + i); System.out.println(); // 换行 } else System.out.print(" " + i); } } } public static void main(String[] args) { PrimeNumber pn = new PrimeNumber(); pn.printPrime(100); // 打印出100 之内的所有质数 } }
程序运行结果:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
2.4.3 递归
递归是相当重要的一种程序设计技术,用递归表达程序设计逻辑十分简明。递归分为两种:直接递归与间接递归。
直接递归是指方法运行时又调用了自身。间接递归是指方法运行时通过调用其他方法,最终又调用自身,如图2-4所示。
图2-4 间接递归
【例2.10】 递归计算1+2+…+100之和。
Sum.java
public class Sum { static int P(int n) { return n == 0 ? 0 : n + P(n -1); } public static void main(String[] args) { System.out.println("1+2+…+100之和是: " + P(100)); } }
程序运行结果:
1+2+…+100之和是: 5050
【例2.11】 递归计算Fibonacci数列的第5个值。
Fibonacci.java
public class Fibonacci { public static void main(String[] args) { System.out.println(f(5)); } public static int f(int n){ if (n == 1 || n == 2){ return 1; }else { return f(n-1)+ f(n-2); } } }
程序运行结果:5。