方法(普通方法)、方法执行内存分析、 方法重载机制、方法递归

一、方法 

以下的程序不使用"方法" 分析有哪些缺点? 代码冗余
以下相同的代码写了三遍(只不过每次参与求和的数据不同)代码没有得到重复使用。
应该在java语言中有这样一个机制:
    -某个功能代码只需要写一遍
    -要使用这个功能,只需要给这个功能传递具体的数据
    -这个功能完成之后返回一个最终的结果。

*** 方法定义在类体当中,在一个类当中可以定义多个方法,方法编写的位置没有先后顺序,可以随意。 !!! 但是方法体当中不能再定义方法!!!!!!!

public  class A
{	
	public static void main(String[] args){
		//需求1:计算10+20的和 并输出结果 【功能:计算两个int类型数据的和】
		int a=10;
		int b=20;
		int c=a+b;
		System.out.println(c);
		// 需求2: 计算30+40的和 并输出结果 【功能:计算两个int类型数据的和】
		int d=30;
		int e=40;
		int f=d+e;
		System.out.println(f);
		// 需求3: 计算50+60的和 并输出结果 【功能:计算两个int类型数据的和】
		int g=50;
		int h=60;
		int i=g+h;
		System.out.println(i);
	}
} 

关于java语言当中的方法:
    1、方法怎么定义,语法结构:

    【修饰符列表】 返回值类型 方法名{形式参数列表}{
        方法体;
    }

    2、对以上的语法结构进行解释说明:
        2.1、关于修饰符列表    
            * 可选项,不是必须的
            * 目前统一写成:public static
            * 方法的修饰符列表当中“有static关键字”的话,怎么调用这个方法?
                - 类名.方法名(实际参数列表);
        2.2、返回值类型
            * 什么是返回值?
                一个方法是可以完成某个特定功能的,这个功能结束之后大多数都是需要
                返回最终的结果的,执行结果可能是一个具体存在的数据,而这个具体存
                在的数据就是返回值。
            * 返回值类型?
                返回值是一个具体存在的数据,数据都是有类型的,此处需要指定的是返
                回值的具体类型。
            * 返回值类型都可以指定哪些类型呢?
                java任意一种类型都可以,包括基本数据类型和所有的引用数据类型。

            * 返回值

             return 值;   并且要求"值"的数据类型必须和“方法的返回值类型”一致。 

             返回值类型是void的时候,在方法体当中不能(用)编写"return 值;"这样的

             语句。但是要注意可以编写"return;"这样的语句。

             只要带有return关键字的语句执行,return语句所在的方法结束。【不是JVM结束,是return所在的方法结束】

             *形式参数列表: 简称形参

             形参是局部变量:int a; double b; float c;

 代码框架如下

public class A		// 汽车工厂
{
	public static void main(String[] args){
		//调用这个方法
	}
	// 定义一个方法	
	// 一个车间
	public static int sumInt(int a, int b){
		
	}
}

简单的代码演示 

public class A		
{
	//主方法就需要这样固定的编写,这是程序的入口。
	public static void main(String[] args){
		// 在程序的入口进行调用(可调用多次)

		A.sumInt(10,20);	// 形式参数列表类型为int类型
			
	}

	// 修饰符列表:public static
	// 返回值类型: void
	// 方法名: sumInt
	// 形式参数列表: (int a, int b)
	public static void sumInt(int a, int b){
		int c =a+b;
		System.out.println(a+"+"+b+"="+c);
	}
}

方法的调用不一定都在main方法当中,可以在其他方法当中。只要是程序可以执行到的位置,都可以去调用其他方法。

 代码演示:

public class A		
{
	
	public static void dosome(int a,int b){
		int c =a-b;
		System.out.println(a+"-"+b+"="+c);
		A.sumInt(10,20);	// 再调用sumInt方法
	}
	// 主方法程序入口
	public static void main(String[] args){
		A.dosome(60,50);		// 先调用dosome方法	
		
		System.out.println("hello world!");	// 最后输出hello world!

	}

	public static void sumInt(int a, int b){
		int c =a+b;
		System.out.println(a+"+"+b+"="+c);
		
	}
	
}

输出结果 

方法调用的时候实参和形参要求个数对应相同,数据类型对应相同。 类型不同的时候要求能够进行相应的自动类型转换

代码演示如下: 

public class A		
{
	public static void main(String[] args){
		
		A.sumLong(10L,20L);	

		// 存在自动类型转换 int--->long (小容量到大容量)
		
		A.sumLong(10,20);
		// 编译错误 3.0为double类型(大容量)
		//A.sumLong(3.0,20);

		A.sumLong((int)(3.0),20);	// 添加转换符(精度会损失)



	}
	public static void sumLong(long a,long b){
		System.out.println(a+"+"+b+"="+(a+b));
	}
}

    方法的返回值类型不是void的时候。
        返回值类型不是void的时候:
            要求方法必须保证百分百的执行"return 值;"这样的语句来完成值得返回。
            没有这个语句编译器会报错。
 

需求:
            请定义并实现一个方法,该方法可以计算两个int类型数据的商,
            要求将最终的计算结果返回给调用者

代码演示1:(没有接收返回值的情况如下) 

public class A
{
	public static void main(String[] args){
		A.divide(30,10);	// 此时调用后程序能够运行 但没有接收返回值
		
	}
		public static int divide(int a,int b){
			
			//int c =a/b;
			//return c;	//返回的值c必须和返回值类型int类型一致
						// 不一致则会报错
						// 例如报错类型有(return;  return true;   return其他数据类型的值;)
			return a/b;
		}
	}

一般调用别人的方法都会接收方法中的数据,接收数据代码如下:

public class A
{
	public static void main(String[] args){
		//采用变量接收: 变量要和返回值的数据类型一致
		// 第一种接收:
		int i=A.divide(30,10);	
		System.out.println(i);
		
		// 第二种接收:
		long x=A.divide(30,10);	// 整数型中:小容量转换成大容量
		System.out.println(x);

		// 第三种接收:
		System.out.println(A.divide(30,10));
		
	}
		public static int divide(int a,int b){
			
	
			return a/b;
		}
	}

深入return语句

深入return语句
    * 带有return关键字的java语句只要执行,所在的方法执行结束。
    * 在"同一个作用域"当中,return语句下面不能编写任何代码,因
    为这些代码永远都执行不到,所以编译错误。

public class A
{
	public static void main(String[] args){
		 /* 
		 // 接收成功
		 int i=A.m();
		 System.out.println(i);
		 */

		 //报错: 把m当成了变量
		 //System.out.println(A.m);
		 
		 // 成功
		 System.out.println(A.m());
		
	}

	public static int m(){
		
		/*
		int a=10;
		if (a>3) //报错:缺少返回语句  因为编译器只能知道要判断a>3 不知道是false 还是 true
				 //		如果是false的话 则在int返回值类型中没有返回语句 所以报错。
				 //   也就是说无法保证return 1;百分百被执行。
		{
			return 1;
		}
		*/

		
		// 编译成功 因为编译器假如判断a>3为false时候 还能else输出返回语句 return 0;
		int a=10;
		if (a>3)
		{
			return 1;
			// 这里不能编写代码,编译错误,因为return下面无法访问到该语句
			//System.out.println("hello world!");
		}
		else{
			// 编译成功: 当a<=3的时候能访问到该语句
			System.out.println("hello world!");
			return 0;
			// 同理 访问不到该语句
			//System.out.println("hello world!");
		}
		
		
		//也可以用三元运算符进行改写代码
		//return 10>3? 1:0;

	}
}

 在返回类型是void的方法当中使用“return;”语句。 "return;"语句出现在返回值为void的方法当中主要是为了结束当前方法。

代码演示: 

public class A
{
	public static void main(String[] args){
		A.m();
		for (int i=10;i>1 ;i-- )
		{
			if (i==2)
			{
				return;
			}
			System.out.println("data--->:"+i);
			
		}
		// 不会被执行i==2时return;已经终止main()方法
		System.out.println("junker");
	}

	public static void m(){
		/*
		 编译错误:不兼容的类型: 意外的返回值(对于结果类型为空的方法,无法返回值)
		 return 10;
		*/
		for (int a=0;a<=10 ;a++ )
		{
			if (a==5)
			{
				return;	// return 作用: 不是终止for循环, 是终止m()方法。
				
			}
			System.out.println("a--->"+a);
		}
		// 不会被执行 a==5时return;已经终止m()方法
		System.out.println("hello world!");
	}
}

 return; 和 break; 的区别

public class A
{
	public static void main(String[] args){
		A.m();
	}

	public static void m(){
		/*
		 编译错误:不兼容的类型: 意外的返回值(对于结果类型为空的方法,无法返回值)
		 return 10;
		*/
		for (int a=0;a<=10 ;a++ )
		{
			if (a==5)
			{
				return;	// return 作用: 不是终止for循环, 是终止m()方法。
				//break; // 终止的是for循环
			}
			System.out.println("a--->"+a);
		}
		System.out.println("hello world!");
	}
}

 

重点!!!

方法在执行过程当中,在JVM中的内存是如何分配的呢? 内存是如何变化的?

/*
    方法在执行过程当中,在JVM中的内存是如何分配的呢? 内存是如何变化的?
    
    1、方法只定义不调用,是不会被执行的,并且在JVM中也不会给该方法分配"运行所属"的内存空间。
    
    2、在JVM内存划分上有这样三块主要的内存空间:
        *方法区内存【方法区
        *堆内存【堆区
        *栈内存【栈区
    
    3、关于"栈"数据结构:
        *栈:stack,是一种数据结构
        *数据结构反映的是数据的存储形态
        *作为程序员需要提前精通:数据结构+算法
    
    4、方法代码片段存在哪里?方法执行的时候执行过程的内存在哪里分配?
        *方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候,
        将其放到了方法区当中。所以JVM中的三块主要的内存空间中方法区内存最先有
        数据。存放了代码片段

        *代码片段虽然在方法区内存当中只有一份,但是可以被重复调用
        每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配

    5、方法在调用的瞬间,会给该方法分配内存空间,会在栈中发生压栈动作
        方法执行结束之后,给该方法分配的内存空间全部释放,此时发生弹栈动作
            *压栈:给方法分配内存
            *弹栈:释放该方法的内存空间
    
    6、局部变量在"方法体"中声明,局部变量运行阶段内存在栈中分配


*/

对栈进行图像分析描述 

 

方法执行内存分析

public class A {
public static void main(String[] args){
	int a =10;
	int b =20;
	int retValue =sumInt(a,b);
	System.out.println("retValue>>>:"+retValue);
	}

public static int sumInt(int i,int j){
	int result = i+j;
	int num =3;
	int retValue = divide(result,num);
	return retValue;
}

public static int divide(int x,int y){
	int z=x/y;
	return z;
}
				
}

 二、方法重载

以下代码不使用"方法重载机制",不使用overload,分析程序存在的缺点?

    1、sumInt,sumLong,sumDouble方法虽然功能不同,但是功能是相似的。都是求和。
     在以下程序当中功能相似的方法,分别起了三个不同的名字,这对于程序员来说,调用
     方法的时候不方便,程序员需要记忆更多的方法,才能完成调用【不方便】
    
    2、代码不美观。

    有没有这样的一种机制:
        功能虽然不同,但是“功能相似”的时候可以让程序员更加的方便。
        方法重载机制:Overload

public class A
{

public static void main(String[] args){
	int result1 =sumInt(1,2);
	System.out.println(result1);
	long result2 =sumLong(1L,2L);
	System.out.println(result2);
	double result3 =sumDouble(1.0,2.0);
	System.out.println(result3);
}
	
public static int sumInt(int a,int b){
	return a+b;
}
public static long sumLong(long a,long b){
	//long c =a+b;
	//return c;
	return a+b; // a+b 为long型
}
public static double sumDouble(double a,double b){
	return a+b;	
}
}

 体验以下方法重载的优点:(两者结果相同  优点: 不再记方法名了 ,此时区分方法不再依靠方法名了,依靠的是参数的数据类型。)

public class A
{

public static void main(String[] args){
	
	//调用方法的时候就像在使用一个方法一样
	//参数的类型不同,对应调用的方法也不同
	//此时区分方法不再依靠方法名了,依靠的是参数的数据类型。
	System.out.println(sum(1,2));
	System.out.println(sum(1L,2L));
	System.out.println(sum(1.0,2.0));
}
// 以下三个方法构成了方法重载机制
// sum方法名
public static int sum(int a,int b){	
	return a+b;
}
// sum方法名
public static long sum(long a,long b){
	
	return a+b; 
}
// sum方法名
public static double sum(double a,double b){
	return a+b;		
} 
}

加强了解方法重载机制

    方法重载:

    1、方法重载又被称为:overload

    2、什么时候考虑使用方法重载?
        * 功能相似的时候 尽可能让方法名相同。
        【但是功能不同/不相似的时候 极可能让方法名不同】
    
    3、什么条件满足之后构成了方法重载?
        *在同一个类当中
        *方法名相同
        *参数列表不同:
            数量不同 or 顺序不同 or 类型不同
    
    4、方法重载和什么有关系,和什么没关系?
        * 方法重载和方法名+参数列表有关系
        * 方法重载和返回值类型无关
        * 方法重载和修饰符列表无关
 

public class A
{

public static void main(String[] args){
	m1();
	m1(1);
	m2(2,2.0);
	m2(2.0,2);
	m3(3);
	m3(3.0);

}
//以下两个方法构成重载如下:
// 参数列表数量不同时:
public static void m1(){}
public static void m1(int a){}

// 参数顺序不同时:
public static void m2(int a,double b){}
public static void m2(double a,int b){}

// 参数类型不同时:
public static void m3(int x){}
public static void m3(double y){}

/*
编译错误:以下两个方法都不是构成方法重载,是发生了方法重复
public static void m4(int a,int b){}
public static void m4(int b,int a){}

编译错误:
public static void m5(){}
public static int m5(){
	return 1;
}

编译错误:
void y(){}
public static void y(){}

*/
}

 报错结果如下:

 方法重载的应用:

可以自定义一个封装包

 

 然后直接进行调用

 结果如下:

 三、递归******

    关于方法的递归调用
        1、 什么是递归?
            方法自身调用自身。
        2、递归很耗费内存的,递归算法可以不用的时候尽量不使用。
        3、以下程序运行的时候发生了这样的一个错误【不是异常,是错误Error】:
            java.lang.StackOverflowError
            栈内存溢出错误。
            错误发生无法挽回,只有一个结果,就是JVM停止工作。
        4、递归必须有结束条件,没有结束条件一定会发生栈内存溢出错误。
        5、递归即使有了结束条件,即使结束条件是正确的,也肯能发生栈内存溢出错误,因为递归的太深了。

public class A
{
	public static void main(String[] args){
		System.out.println("main begin");
		doSome();
		System.out.println("main over");

	}

// 以下代码片段虽然只有一份
// 但是可以被重复调用,并且只要调用doSome方法就会在栈内存中新分配一块所属的内存空间。
	public static void doSome(){
		System.out.println("doSome begin");
		doSome();	//这行代码不结束 下面的代码是不能够被执行的。
		System.out.println("doSome over");
	}
	
}

 运行结果:

 不使用递归 求1~N的和

public class A
{
	/*
	public static void main(String[] args){
		/*
		int sum=0;
		for (int a=1;a<=4 ;a++ )
		{
			sum+=a;
		}
		System.out.println("sum:"+sum);
		*/
// 以上计算的1~4的和 是没有学习方法的时候运用的 
// 学习完方法后要学会运用方法来进行完成代码

public static void main(String[] args){
	System.out.println(sumInt(4)); 
}	
//单独的定义一个方法,这是一个独立的功能,可以完成1~N的求和
	public static int sumInt(int n){
		int sum =0;
		for (int a=1;a<=n ;a++ )
		{	
			sum+=a;	
		}
		return sum;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值