JavaSE_方法,递归,内存分析

1.方法:

1.1 概述和作用

* 方法:就是一堆代码的集合,一般一个方法用于完成一个特定的功能(只保证功能的实现,最终用在什么地方,与声名无关)

* 优点:代码复用,易维护,易扩展,灵活性高

1.2 方法的声名

* 修饰符列表 返回值类型 方法名 (参数列表){

* 方法体

* }

* 修饰符列表:可以有,也可以没有,可以有多个,用空格隔开,不区分顺序

* 权限修饰符:public,protected,private,默认(四选一)

* 返回值类型:可以为十一种数据类型中的任何一种,没有返回值可以写void

* 方法名:符合命名规则即可

* 参数列表:可以没有,也可以有多个,中间用逗号隔开,参数列表中的变量也是局部变量

* 方法体:方法中的功能代码

* return:中止方法运行,并返回结果,如果方法中有返回值类型,则必须有return语句

* 如果方法中没有返回值类型,return则可写可不写,如果写了return则只是中止方法运行,不会返回数据

1.3 方法的分类

* 成员方法:没有使用static修饰的方法

* 静态方法:使用static修饰的方法

* 构造方法:之后再说

    //无参无返回值的静态方法
	public static void m1() {};
	//有参无返回值的静态方法
	public static void m2(int a) {};
	//多参无返回值的静态方法
	public static void m3(int a,double b) {};
	//有参有返回值的静态方法
	public static int m4(int a,int b) {
		return 10;
	};
	//有参无返回值的成员方法
	public void m5(int a) {};
1.4 方法调用

* 静态方法:类名.方法名(参数) 同一个类中可以省略类名

* 成员方法:对象.方法名(参数)

    public static void main(String[] args) {
		//注意:方法不调用不执行,调用才执行,并把结果返回给调用出处,所以不需要考虑方法声名的先        
        //后顺序
		Method_01.m1();
		//当前类中类名可忽略
		m1();
		//如果方法中有参数,则我们调用时,必须传入对应的数据(类型和个数都要对应)
		m2(2);
		//如果我们调用有返回值的方法,我们一般需要一个变量来接受返回值
		int restlt = m4(1,2);
}
1.5 入参和出参

* 形参:形容参数,方法声名时,指定的参数列表,称为形参

* 实参:实际参数,调用方法时传入的具体参数

* 入参:参数列表,调用方法时需要传入的数据

* 出参:返回值,方法执行时需要返回的数据

1.6 方法重载

* Overload:方法重载

* 方法名相同,参数列表不同,就是方法重载

* 参数列表不同分为两种

* 1.参数个数不同

* 2.参数类型不同

* 优点:功能相同,名字相同,方便记忆,代码美观

public class Method_03 {
	public static void main(String[] args) {
		sumInt(10,20);
		sumDouble(10.2,20.8);
		sumLong(22L,13L);
		//重载之后
		sum(12,10);
		sum(11.0,12.0);
		sum(13L,98L);
		
		//以下也是方法的重载
		System.out.println("你好");
		System.out.println(12);
		System.out.println(12.9);
		System.out.println(false);
	}
	
	
	public static void sumInt(int a,int b) {
		System.out.println(a+b);
	}
	public static void sumDouble(double a,double b) {
		System.out.println(a+b);
	}
	public static void sumLong(Long a,Long b) {
		System.out.println(a+b);
	}
	//重载后
	public static void sum(int a,int b) {
		System.out.println(a+b);
	}
	public static void sum(double a,double b) {
		System.out.println(a+b);
	}
	public static void sum(Long a,Long b) {
		System.out.println(a+b);
	}
}
1.7 方法调用时类型转换
public static void main(String[] args) {
		//自动类型转换、
		//由于前面是double,所以后面的9会转换为double,匹配double对应的方法
		m1(1.5,7);
		
		//由于两个都是int,所以转换为long,而不是double
		m1(1,2);
	}
	
	public static void m1(long a,long b) {
		System.out.println("long...");
	}
	public static void m1(double a,double b) {
		System.out.println("double...");
	}

2.内存分析

* JVM运行时区域

* 程序计数器:暂时不管

* 静态区/方法区:用来保存运行时的class文件和静态属性和方法的

* VM栈:是以栈数据结构为模型,开辟一块空间,先进后出

* 用于执行方法,每一个方法的调用,就是一个栈帧,一般main方法为栈底元素

* 方法调用就是等于压栈,方法执行完成就等于出栈

*

* 栈帧:在栈内存中保存的数据空间

* 栈底元素:第一个放入栈空间的栈帧

* 栈顶元素:最后一个放入栈空间的栈帧

* 压栈:把栈帧放入栈空间的过程

* 弹栈:把栈帧在栈空间弹出的过程

* 堆内存:用于保存对象

* 本地方法栈:和VM栈一样,只不过用于执行本地方法

3.递归

3.1 概述和基本应用

* 递归:递归就是在方法中调用当前方法

* 直接递归:当前方法中对自身方法进行调用

* 间接递归:A方法调用B方法,B方法调用A方法

* 递归和迭代:递归和迭代是等价的,都需要中止条件,否则就是死循环

* 报错:java.lang.StackOverflowError:栈内存溢出,一般是因为一直压栈没有弹栈导致

* 原因:1.递归没有中止条件,出现死循环

*            2.递归代码没有问题,但是因为要计算的功能比较大,导致压栈过多

* 注:递归比较消耗内存,效率较低,所以能用循环解决的问题一般不适用递归,循环能做的递归一定能做,但是递归能做的循环不一定能做

* 一般树状结构一类的,循环做不了,需要使用递归去做,如文件夹的嵌套关系(例如:要获取某文件夹下所有的文件包含子文件)

public static void main(String[] args) {
		m1();
	}
	
	//直接递归
	public static void m1() {
		m1();
	}
	//间接递归
	public static void m2() {
		m3();
	}
	public static void m3() {
		m2();
	}
3.2 计算1~n的加加
    //递归做
	public static int test1(int n) {
		if(n == 1) {
			return 1;
		}
		return n + test1(n-1);
	}
	
	//循环做
	public static int test2(int n) {
		int sum = 0;
		for(int i = 1;i <= n;i++) {
			sum+=i;
		}
		return sum;
	}
3.3 斐波那契数列
/*
	 * 前两位是1,后续每一位都是前两位的和
	 * 1  1  2  3  5  8  13
	 */
	public static int test(int n) {
		if(n == 1 || n == 2) {
			return 1;
		}else {
			return test(n-1) + test(n-2);
		}
	}
	public static void main(String[] args) {
		int result = test(10);
		System.out.println(result);
		
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值