Java中的方法和递归
方法的定义
示例代码:
public class Demo1 {
public static void main(String[] args) {
int num = sum(1,2);
System.out.println(num);
}
/**
*
* @param a 形参1
* @param b 形参2
* @return 形参1和形参2的和
*/
public static int sum (int a ,int b){
return a+b;
}
}
方法是语句的集合,他们在一起执行一个功能。
-
方法的命名规则与变量一样,首字母小写,其他单词首字母大写。
-
方法是解决一类问题的步骤的有序组合
-
方法包含于类或对象中
-
方法在程序中被创建,在其他地方被调用
方法本意是功能块,就是实现某一个功能的语句集合,我们设计方法的时候最好保持方法的原子性,就是一个方法只完成一个功能,这样有利于程序后期的拓展。
例:System.out.println()
-
System是类。
-
out是对象。
-
println是方法。
-
()中是方法的参数。
方法的结构
示例代码:
public class Demo1 {
public static void main(String[] args) {
int a = 1; //实参1
int b = 2; //实参2
int num = sum(a,b); //调用方法将实参传送到方法内
System.out.println(num);
}
/**
* @public 修饰符
* @static 修饰符
* @int 返回值类型
* @sum 方法名
* @param a 定义形参1接收实参1的值
* @param b 定义形参2接收实参2的值
* @return 形参1和形参2的和
*/
public static int sum (int a ,int b){
//方法内其实是把实参的值赋给形参使用形参进行运算。
return a+b;
//方法体
}
}
-
修饰符(可选)
告知编译器如何调用该方法,定义了该方法的访问类型。
-
返回值类型
根据设计需求,方法可能会有各种各样的返回值,需要定义返回值的类型,如果没有返回值,则返回值类型为void。
-
方法名
方法的实际名称,方法名和参数表共同构成方法签名。
-
参数类型
形参,作用域为当前方法内,当方法被调用时需根据方法的形参传递值给参数,这个值被称为实参,在方法中实参的值被赋给形参进行运算。
-
形参
在方法被调用时用来接收外部的数据
-
实参
调用方法时实际传给方法的数据。
-
-
方法体
包含具体的执行语句,定义该方法的功能。
-
return语句
如果方法定义有返回值,则需要使用return语句返回对应的数据,return语句的另一个作用是终结方法。
方法的调用
Java支持两种调用方法的方式,根据是否有返回值来选择。
-
当方法返回一个值的时候,方法通常被当作一个值来使用。
示例代码:
import java.util.Scanner; public class Demo2 { public static void main(String[] args) { double a = 0; double b = 0; Scanner scanner = new Scanner(System.in); while (true) { System.out.println("请输入第一个数字:"); if (scanner.hasNextDouble()) { a = scanner.nextDouble(); break; } else { System.out.println("您的输入有误,请重新输入。"); } } while (true) { System.out.println("请输入第二个数字:"); if (scanner.hasNextDouble()) { b = scanner.nextDouble(); break; } else { System.out.println("您的输入有误,请重新输入。"); } } System.out.println("两个数中最大的数字为:"+max(a,b)); //调用方法,直接当作一个值使用。 } public static double max(double a, double b) { if (a == b) { System.out.print("两个数字相等,结果为:"); return 0; } else if (a > b) { return a; } else { return b; } } }
-
当方法返回值为void的时候,方法的调用一定是一个语句。
示例代码:
public class Demo3 { public static void main(String[] args) { System.out.println("这个方法被当作一个语句执行了"); } }
方法的重载
方法的重载就是在一个类中,有相同的方法名称,但形参不同的方法。
示例代码:
public class Demo3 {
public static void main(String[] args) {
int a = 10;
int b = 10;
double c = 3.14;
double d = 6.66;
System.out.println(max(c, d));
System.out.println(max(a, b));
}
public static int max(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
public static double max(double a, double b) {
if (a > b) {
return a;
} else {
return b;
}
}
}
以上代码使用了方法的重载将使max方法对两个类型的变量都能够使用。
重载规则:
-
方法名必须相同
-
方法参数列表必须不同
-
仅返回类型不同不足以成为方法的重载
-
方法名相同时,编译器会根据方法的参数个数、类型等逐个去匹配,如果匹配失败则会报错。
方法的命令行传参
某些特殊情况下,我们需要在程序运行后再传递给他消息,这需要依靠传递参数给main方法。
示例代码:
package base;
public class Demo4 {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
编译和运行:
可变参数
示例代码:
public class Demo4 {
public static void main(String[] args) {
Demo4 demo4 = new Demo4();
demo4.list(1,3,2,15,15,123,12312415);
}
public void list(int... a){
for (int x:a){
System.out.println(x);
}
}
}
-
从JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
-
在方法声明中,在指定参数的类型后面加一个省略号...。
-
一个方法只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前。
-
可变参数也叫做不定项参数,常用于传递不确定边界的数组或集合。
递归
递归就是在方法的方法体中调用本方法,也就是调用自己。利用递归可以通过简单的程序解决一些复杂的问题。
递归的能力在于用有限的语句来定义对象的无限集合。
示例代码:
/**
* 阶乘:1的阶乘:1*1
* 2的阶乘:2*1
* 5的阶乘:5*4*3*2*1
* 10的阶乘:10*9*8*7*6*5*4*3*2*1
* <p>
* 计算10的阶乘,并输出结果。
*/
public class Demo5 {
public static void main(String[] args) {
System.out.println(factorial(10));
}
public static int factorial(int n) {
if (n == 1) { //递归头
return 1;
} else {
return n * factorial(n - 1); //递归体
}
}
}
递归结构必须包含两个部分,递归头和递归体。
-
递归头
什么时候不调用自身方法,如果没有头则死循环,程序栈溢出。
-
递归体
什么时候需要调用自身方法。
以以上示例代码浅谈递归执行顺序:
-
程序开始执行,执行到main方法,并执行到println方法。
-
println参数中调用了factorial方法代入实参5计算实参的阶乘并返回给println方法。
-
程序开始执行最开始的方法调用,调用factorial方法代入实参5赋值给形参n。
-
执行if语句,开始判断n是否为1。(此时n为5)
-
if条件不满足,进入else分支,返回n*factorial方法的返回值,factorial方法代入实参n-1。(此处带入4)
-
开始第一次递归,factorial方法受到调用,开始执行,代入实参4赋值给形参n。
-
因不满足if条件(此时n为4),进入else分支开始计算n*factorial方法的返回值,factorial方法代入实参n-1(此处带入3)
-
开始第二次递归,factorial方法受到调用,开始执行,代入实参3赋值给形参n。
-
因不满足if条件(此时n为3),进入else分支开始计算n*factorial方法的返回值,factorial方法代入实参n-1(此处带入2)
-
开始第三次递归,factorial方法受到调用,开始执行,代入实参2赋值给形参n。
-
因不满足if条件(此时n为2),进入else分支开始计算n*factorial方法的返回值,factorial方法代入实参n-1(此处带入1)
-
开始第四次递归,factorial方法受到调用,开始执行,代入实参1赋值给形参n。
-
因此时n为1所以if条件满足,执行if中的语句,返回值1。
-
第四次递归的返回值1返回给第三次递归进行运算,即n * factorial(n - 1),此时factorial(n - 1)的值为1,即计算2 * 1的值。(因第三次递归时n的值为2)
-
第三次递归的返回值2返回给第二次递归进行运算,即n * factorial(n - 1),此时factorial(n - 1)的值为2,即计算3 * 2的值。(因第二次递归时n的值为3)
-
第二次递归的返回值6返回给第一次递归进行运算,即n * factorial(n - 1),此时factorial(n - 1)的值为6,即计算4 * 6的值。(因第一次递归时n的值为4)
-
第一次递归的返回值24返回给最开始的方法调用进行运算,即n * factorial(n - 1),此时factorial(n - 1)的值为24,即计算5 * 24的值。(因最开始我们传入的实参为5)
-
方法全部运行结束,返回值5*24的结果,即120。回到主程序,执行System.out.println(120);。
-
打印结果120。
Java是利用栈的语言,程序运行在栈中,每个方法、每个变量都在栈中有自己的空间。
递归其实是一种压栈的方法,每递归当前方法一次,储存方法的栈则多压一层,递归结束后栈才会"释压",当栈满时则会溢出,内存崩溃。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人