Java方法的参数传递机制与递归总结

文章目录

      • 1、方法的参数传递机制
        • 1.1、形参和实参
        • 1.2、 参数传递机制:值传递
        • 1.3、 举例
        • 1.4 练习
      • 2、 递归(recursion)方法

1、方法的参数传递机制

1.1、形参和实参

若方法含有参数:

  • 形参(formal parameter):在定义方法时方法名后面括号中声明的变量称为形式参数(简称形参)即形参出现在方法定义时。
  • 实参(actual parameter):调用方法时方法名后面括号中的使用的值/变量/表达式称为实际参数(简称实参)即实参出现在方法调用时。
1.2、 参数传递机制:值传递

Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

  • 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参

  • 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参

1.3、 举例

1、形参是基本数据类型

案例:编写方法,交换两个整型变量的值

public class ValueTransferTest1 {public static void main(String[] args) {int m = 10;int n = 20;System.out.println("m = " + m + ", n = " + n);//交换m和n的值
//		int temp = m;
//		m = n;
//		n = temp;ValueTransferTest1 test = new ValueTransferTest1();test.swap(m, n);System.out.println("m = " + m + ", n = " + n);}public void swap(int m,int n){int temp = m;m = n;n = temp;}}

内存解析:

在这里插入图片描述

2、形参是引用数据类型

public class ValueTransferTest2 {public static void main(String[] args) {Data d1 = new Data();d1.m = 10;d1.n = 20;System.out.println("m = " + d1.m + ", n = " + d1.n);//实现 换序ValueTransferTest2 test = new ValueTransferTest2();test.swap(d1);System.out.println("m = " + d1.m + ", n = " + d1.n);}public void swap(Data data){int temp = data.m;data.m = data.n;data.n = temp;}
}
class Data{int m;int n;
}

内存解析:

在这里插入图片描述

1.4 练习

练习1:判断如下程序输出的结果

public class AssignNewObject {public void swap(MyData my){my = new MyData(); //考虑堆空间此新创建的对象,和main中的data对象是否有关int temp = my.x;my.x = my.y;my.y = temp;}public static void main(String[] args) {AssignNewObject tools = new AssignNewObject();MyData data = new MyData();data.x = 1;data.y = 2;System.out.println("交换之前:x = " + data.x +",y = " + data.y);//tools.swap(data);//调用完之后,x与y的值交换?System.out.println("交换之后:x = " + data.x +",y = " + data.y);//}
}class MyData{int x ;int y;
}

练习2:如下操作是否可以实现数组排序

public class ArrayTypeParam {//冒泡排序,实现数组从小到大排序public void sort(int[] arr){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if(arr[j] > arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}//打印数组的元素public void print(int[] arr){for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}System.out.println();}public static void main(String[] args) {ArrayTypeParam tools = new ArrayTypeParam();int[] nums = {4,3,1,6,7};System.out.println("排序之前:");tools.print(nums);tools.sort(nums);//对nums数组进行排序System.out.println("排序之后:");tools.print(nums);//输出nums数组的元素}
}

练习3:通过内存结构图,写出如下程序的输出结果

//栈:每个方法在调用时,都会有以栈帧的方法压入栈中。栈帧中保存了当前方法中声明的变量:方法内声明的,形参
//堆:存放new出来的"东西":对象(成员变量在对象中)、数组实体(数组元素)。 
//注意:变量前如果声明有类型,那么这就是一个新的刚要定义的变量。如果变量前没有声明类型,那就说明此变量在之前已经声明过。
public class TransferTest3 {public static void main(String args[]) {TransferTest3 test = new TransferTest3();test.first();}public void first() {int i = 5;Value v = new Value();v.i = 25;second(v, i);System.out.println(v.i);}public void second(Value v, int i) {i = 0;v.i = 20;Value val = new Value();v = val;System.out.println(v.i + " " + i);}
}class Value {int i = 15;
}

内存解析:

在这里插入图片描述

练习4:貌似是考查方法的参数传递

在这里插入图片描述

	//法一:public static void method(int a, int b) {// 在不改变原本题目的前提下,如何写这个函数才能在main函数中输出a=100,b=200? a = a * 10;b = b * 20;System.out.println(a);System.out.println(b);System.exit(0);}//法二:public static void method(int a, int b) {PrintStream ps = new PrintStream(System.out) {@Overridepublic void println(String x) {if ("a=10".equals(x)) {x = "a=100";} else if ("b=10".equals(x)) {x = "b=200";}super.println(x);}};System.setOut(ps);}

练习5:将对象作为参数传递给方法

(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积。
(2)定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:public void printAreas(Circle c, int time),在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。
(3)在main方法中调用printAreas()方法,调用完毕后输出当前半径值。程序运行结果如图所示。

在这里插入图片描述

2、 递归(recursion)方法

举例1:

在这里插入图片描述

举例2:

从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥?从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥?从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥?从前有座山,山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事,讲的啥?...老和尚没了,庙塌了,小和尚还俗结婚了。

递归方法调用:方法自己调用自己的现象就称为递归。

**递归的分类:**直接递归、间接递归。

  • 直接递归:方法自身调用自己。

    public void methodA(){methodA();
    }
    
  • 间接递归:可以理解为A()方法调用B()方法,B()方法调用C()方法,C()方法调用A()方法。

    public static void A(){B();
    }public static void B(){C();
    }public static void C(){A();
    }
    

说明

  • 递归方法包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
  • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,停不下来,类似于死循环。最终发生栈内存溢出

举例:

举例1:计算1 ~ n的和

public class RecursionDemo {public static void main(String[] args) {RecursionDemo demo = new RecursionDemo();//计算1~num的和,使用递归完成int num = 5;// 调用求和的方法int sum = demo.getSum(num);// 输出结果System.out.println(sum);}/*通过递归算法实现.参数列表:int 返回值类型: int */public int getSum(int num) {/* num为1时,方法返回1,相当于是方法的出口,num总有是1的情况*/if(num == 1){return 1;}/*num不为1时,方法返回 num +(num-1)的累和递归调用getSum方法*/return num + getSum(num-1);}
}

代码执行图解:

在这里插入图片描述

举例2:递归方法计算n!

public int multiply(int num){if(num == 1){return 1;}else{return num * multiply(num - 1);}
}

在这里插入图片描述

举例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。

public int f(int num){if(num == 0){return 1;}else if(num == 1){return 4;}else{return 2 * f(num - 1) + f(num - 2);}
}

举例4:已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值。

public int func(int num){if(num == 20){return 1;}else if(num == 21){return 4;}else{return func(num + 2) - 2 * func(num + 1);}
}

举例5:计算斐波那契数列(Fibonacci)的第n个值,斐波那契数列满足如下规律,

1,1,2,3,5,8,13,21,34,55,....

即从第三个数开始,一个数等于前两个数之和。假设f(n)代表斐波那契数列的第n个值,那么f(n)满足:
f(n) = f(n-2) + f(n-1);

	//使用递归的写法int f(int n) {//计算斐波那契数列第n个值是多少if (n < 1) {//负数是返回特殊值1,表示不计算负数情况return 1;}if (n == 1 || n == 2) {return 1;}return f(n - 2) + f(n - 1);}//不用递归int fValue(int n) {//计算斐波那契数列第n个值是多少if (n < 1) {//负数是返回特殊值1,表示不计算负数情况return 1;}if (n == 1 || n == 2) {return 1;}//从第三个数开始,  等于 前两个整数相加int beforeBefore = 1; //相当于n=1时的值int before = 1;//相当于n=2时的值int current = beforeBefore + before; //相当于n=3的值//再完后for (int i = 4; i <= n; i++) {beforeBefore = before;before = current;current = beforeBefore + before;/*假设i=4beforeBefore = before; //相当于n=2时的值before = current; //相当于n=3的值current = beforeBefore + before; //相当于n = 4的值假设i=5beforeBefore = before; //相当于n=3的值before = current; //相当于n = 4的值current = beforeBefore + before; //相当于n = 5的值....*/}return current;}

举例6:面试题

面试,遇到一个一个双重递归调用的问题,我琢磨了一下,完全不知道为什么。打断点了,也还是没看懂为什么程序会那样走。您有空可以看一下,求指教。

在这里插入图片描述

	private int count = 0;public int recursion(int k) {count++;System.out.println("count1:" + count + "  k:" + k);if (k <= 0) {return 0;}return recursion(k - 1) + recursion(k - 2);//287//return recursion(k - 1);//11//return recursion(k - 1) + recursion(k - 1);//2047}

剖析:

在这里插入图片描述

总结说两句:

  1. 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。

  2. 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。考虑使用循环迭代

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/793180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT背景介绍

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、QT背景 1.1什么是QT 1.2QT的发展历史 1.3什么是框架、库 1.4QT支持的平台 1.5QT的优点 1.6QT的…

BIM转Power BI数据集

在本博客中&#xff0c;我们将了解如何使用从 SSAS 表格、Power BI Desktop 或 Power BI 服务数据集中提取的 Model.bim 文件在本地或 PBI 服务上生成新数据集。 1、设置&#xff08;SSAS 表格和 PBI 服务通用&#xff09; 我建议你创建一个专门用于此任务的新 Python 环境&a…

old photo老照片图像复原数据集

来源 本来想拿DA-CLIP 训练一下old photo&#xff0c;训练代码没成功&#xff0c;毕设没时间就不研究了 github搜old photo复原论文原作者好像没开源训练数据集&#xff0c;所以用了这个SynOld 训练集500对测试集200对 但是readme写的很差&#xff0c;其他什么也没交代 展示…

Centos-Linux安装部署MySQL-8.0

linux搭建mysql 1.使用系统的root账户 2.切换到 /usr/local 目录下 3.下载mysql wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz也可以直接在官方下载最新版本 官方下载 选择linux 4.解压mysql tar xvJf mysql-8.0.21-l…

C易错注意之const修饰指针,含char类型计算,位段及相关经典易错例题

目录 前言 一&#xff1a;const修饰指针 1.const修饰变量 2.const 修饰指针 1.const int*p&m; 2. int* const p&m; 3. int const *p&m; 4. int const *const p&m; 5.总结 总之一句话为&#xff1a;左定值有定向 二&#xff1a;关于计算中char类型…

C语言:动态内存管理(二)

目录 前言 1.3 realloc​编辑 3、常见动态内存管理错误 3.1 对空指针的解引用操作 3.2 对动态开辟的空间进行越界访问 3.3 对非动态开辟内存使用free释放 3.4 使用free释放一块动态内存开辟的一部分 3.5 对同一块空间的多次释放 3.6 动态内存开辟之后忘记释放 总结 前…

杨氏矩阵(C语言)

文章目录 问题技术名词解释思路关键代码运行代码 问题 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 技术名词解释 杨氏矩阵&…

自动化测试框架Robot Framework入门

什么是RF RF是一个基于 Python 的、可扩展的关键字驱动的自动化 验收测试框架、验收测试驱动开发 &#xff08;ATDD&#xff09;、 行为驱动开发 &#xff08;BDD&#xff09; 和机器人流程自动化 &#xff08;RPA&#xff09;。它 可用于分布式、异构环境&#xff0c;其中自动…

Spring Security——04,认证_校验

认证_校验 一、认证过滤器二、配置过滤器三、测试过滤器3.1 登录接口3.2 非登录接口3.3 结果 一键三连有没有捏~~ 一、认证过滤器 创建一个filter包&#xff0c;创建一个过滤器 代码如下&#xff1a; Component public class JwtAuthenticationTokenFilter extends OncePerR…

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改 这一次G老师不好使了 在集群中使用deepspeed默认的端口号29500被占用&#xff0c;显示更改居然不起作用 G老师给的方法也不好使 #!/bin/bash MASTER_ADDRlocalhost MASTER_PORT29501 # 选择一个未被占用的端…

mysql 运算符 语句 字符集 校队集

mysql 运算符 使用select语句可以输出运算的结果 mysql标识符不区分大小写 算数运算符 1./除法 得到的结果是一个小数 %是整数,省略小数 2、除以0不会报错,得到的结果是 null 3.数宇和字符串做加法运算,并不会拼接 比较运算符 1.mysql里面的=是比较运算符,而不是赋值运算…

lora pingpang系统 4

1 深入了解LoRa技术原理 1.1 LoRa扩频通信原理 1.1.1 模拟无线通信&#xff1a; 模拟无线通信是一种使用模拟信号传输数据的通信方式。这种通信方式已经被数字无线通信所取代&#xff0c;因为数字通信具有更高的效率和可靠性。 天线&#xff1a;从空中接收到的无线电波转换成…

数据结构——图的概念,图的存储结构,图的遍历(dfs,bfs)

目录 1.图的定义和术语 2.案例引入 1.六度空间理论 3.图的类型定义 4.图的存储结构 1.邻接矩阵 1.无向图的邻接矩阵表示法 2.有向图的邻接矩阵表示法 3.网&#xff08;有权图&#xff09;的邻接矩阵表示法 代码示例&#xff1a; 2.采用邻接矩阵表示法创建无向图…

MySQL 表的增删改查

文章目录 一、什么是CRUD&#xff1f;二、新增&#xff08;Create&#xff09;1、单行数据 全列插入2、多行数据 指定列插入3、插入特殊类型 三、查询&#xff08;Retrieve&#xff09;1、全列查询2、指定列查询3、表达式查询4、指定别名5、去重6、排序7、条件查询基本查询&a…

java算法day44 | ● 完全背包 ● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ

完全背包理论基础 完全背包和01背包问题唯一不同的地方就是&#xff0c;每种物品有无限件。 体现在代码中就是对背包的遍历顺序不同。01背包是逆序遍历背包&#xff0c;完全背包是顺序遍历背包。 518. 零钱兑换 II class Solution {public int change(int amount, int[] coin…

IMAP的要点:旅行前需要了解的内容

你是否经常因会议而出差&#xff0c;需要在各种设备上灵活地访问你的电子邮件&#xff1f;如果是的话&#xff0c;你可能会想了解你的电子邮件系统是如何通过使用互联网消息访问协议&#xff08;IMAP&#xff09;来工作的&#xff0c;这样当你不在办公桌前时&#xff0c;你可以…

Java基础 - 代码练习

第一题&#xff1a;集合的运用&#xff08;幸存者&#xff09; public class demo1 {public static void main(String[] args) {ArrayList<Integer> array new ArrayList<>(); //一百个囚犯存放在array集合中Random r new Random();for (int i 0; i < 100; …

SpringCloud - 如何本地调试不会注册到线上环境(Nacos)?

问题描述 有时候我们需要本地调试注册到 Nacos 上&#xff0c;但是会影响线上服务的 Feign 请求打到本地导致不通影响了线上业务。 原因分析 一般最传统的解决方案就是修改本地 bootstrap.yml 的 spring.cloud.nacos.discovery.namespace spring:application:name: app-serv…

jvisualvm 使用教程

之前看过 jvisualvm&#xff0c;但是那个时候对 JVM 并不是很熟悉&#xff0c;后面看了下八股文&#xff0c;看了下 JVM 的相关知识之后&#xff0c;发现多了解点 JVM 的东西&#xff0c;对我们 CRUD 其实是有指导意义的&#xff0c;就比如我们通常会 new 一堆的没有用到的对象…

使用 Spring Email 和 Thymeleaf 技术,向新注册用户发送激活邮件(二)

本篇博客对应“2.2 开发注册功能”小结 对应视频: 开发注册功能 开发注册功能-续 注册功能是相对比较复制的功能&#xff0c;对于一个相对复杂的功能&#xff0c;可以把这个功能进行拆解。把这个功能的流程想清楚&#xff0c;就知道怎么拆解了&#xff1a; 也可以按照请求进行…