Java基础 方法执行内存分析-方法的重载机制-方法递归调用

鳄鱼君

发表文章数:643

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Java » Java基础 方法执行内存分析-方法的重载机制-方法递归调用

内存分析

编写以下代码:

public class MethodTest  
{
	
	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 a, int b){
		int result = a + b;
		int retValue = merchant(result,10);

		return retValue;
	}

	public static int merchant(int a,int b){
		int result = a / b;

		return result;
	}

}

分析以下方法执行的内存:

方法区中存储的是代码片段和字节码,也就是会存在MethodTest.class、String.class、System.class,JVM虚拟机会调用main方法,main所属的内存空间会分配在栈内存中,在该空间中存储一个int类型变量a值10,b值20,执行sumInt()方法,此时会在栈内存中开辟另一块属于该方法的内存,并将变量a,b中的值传递给sumInt(),这时候程序会等待sumInt方法执行完毕,才会将返回值赋值给retValue变量。

此时,subInt方法处在栈内存的顶部,即栈顶元素,具有活跃状态,所以会执行该方法,计算机运算并将结果赋值给result变量,接着程序会执行merchant方法,此时sumInt处于等待状态,并且在栈内存中会给merchant方法分配内存空间,叫做压栈,这时候,merchant属于栈顶元素,会执行该方法,计算机运算之后将result结果返回给retValue,merchant方法执行完毕,释放掉内存,在sumInt方法中会return retValue,然后释放内存,main主方法中retValue赋值完成,打印输出!

形式参数和实际参数传递的是值,不是变量:

public class MethodTest  
{
	
	public static void main(String[] args){
		int a = 10;
		sumInt(a);
		System.out.println("a:" + a); //10
	}

	public static void sumInt(int a){
		a++;
		System.out.println(a);//11
	}

	
}

重载机制

现在我们要计算两个int类型的和,两个double类型的和,两个long类型的和,可以分别编写对应的方法:

public class OverloadTest  
{
	public static void main(String[] args){
		//调用方法
		int result1 = sumInt(10,20);
		System.out.println(result1);

		double result2 = sumDouble(10.0,20.0);
		System.out.println(result2);

		long result3 = sumLong(10L,20L);
		System.out.println(result3);
	}
	
	public static int sumInt(int a,int b){
		return a + b;
	}

	public static double sumDouble(double a, double b){
		return a + b;
	}

	public static long sumLong(long a ,long b){
		return a + b;
	}
	
}


以上程序,sumInt,sumDouble,sumLong功能不同,但是都是求和的,也就是功能相似的时候,这时候就可以使用方法重载机制/overload:

public class OverloadTest  
{
	public static void main(String[] args){
		//参数的类型不同,调用的方法也不同
		//区分方法依靠的是参数的数据类型
		int result1 = sum(10,20);
		System.out.println(result1);

		double result2 = sum(10.0,20.0);
		System.out.println(result2);

		long result3 = sum(10L,20L);
		System.out.println(result3);
	}
	
	public static int sum(int a,int b){
		return a + b;
	}

	public static double sum(double a, double b){
		return a + b;
	}

	public static long sum(long a ,long b){
		return a + b;
	}
	
}

满足方法重载机制的条件:

  1. 在同一个类中
  2. 方法名相同
  3. 参数列表不同

方法重载和方法名+参数列表有关;方法重载和返回值无关:

public class OverloadTest  
{
	public static void main(String[] args){

	}
	//编译报错
	/*public static void sum(){
		return ;
	}

	public static int sum(){
		return 1;
	}*/

}

方法重载的应用:

public class OverloadTest
{
    public static void main(String[] args){
        //我们使用下面的方式打印输出
        /*
        System.out.println("鳄鱼君");
        System.out.println(10);
        System.out.println(true);
        */

        //可以使用方法重载机制
        A.p(10);
        A.p(10L);
        A.p(10.0);
        A.p(false);
        A.p("鳄鱼君");
    }

}
//自定义类
class A
{
    public static void p(byte a){
        System.out.println(a);
    }
    public static void p(short a){
        System.out.println(a);
    }
    public static void p(int a){
        System.out.println(a);
    }
    public static void p(long a){
        System.out.println(a);
    }
    public static void p(float a){
        System.out.println(a);
    }
    public static void p(double a){
        System.out.println(a);
    }
    public static void p(boolean a){
        System.out.println(a);
    }
    public static void p(char a){
        System.out.println(a);
    }
    public static void p(String a){
        System.out.println(a);
    }
}

以上代码可以解决重复打印不同的数据类型,代码编译之后会生成p.class字节码文件,在该程序删掉p类,主方法照样可以运行,在其它的java源程序中也可以使用p类,编译一次,永久使用!

递归调用

public class RecursionTest
{
    public static void main(String[] args){
        System.out.println("main begin");
        doSome(); //这行代码结束不了
        System.out.println("main over");//程序永远会不执行到这行
    }

    public static void doSome(){
        System.out.println("鳄鱼君 begin");
        doSome();
        System.out.println("鳄鱼君 over");
    }

}

代码的运行机制很简单,doSome方法永远结束不了,因为在它自己调用自己,没玩,这就导致了栈顶元素一直是doSome,栈内存中会一直给doSome方法开辟空间,但它结束不了,所以就一直处于压栈/入栈状态,栈内存是有限的,不够就会导致栈溢出java.lang.StackOverflowError

递归就两点:自己调用自己必须要有结束条件。即使结束条件是正确的,也有可能发生栈内存溢出错误,因为递归的太深了。递归比较耗时,尽量不要使用!

计算1~n的和(不使用递归):

public class RecursionTest
{
    public static void main(String[] args){
      int n = 10;
      int result = sum(n);
      System.out.println(result);
    }

    public static int sum(int n){
       int result = 0;
       for (int i=1; i<=n; i++)
       {
           result +=i;
       }
       return result;
    }

}

使用递归:

public class RecursionTest
{
    public static void main(String[] args){
        int n = 10;
        int result = sum(n);
        System.out.println(result);
    }

    //递归
    public static int sum(int n){
       if (n==1)
       {
           return 1;
       }
       return n + sum(n-1);
    }

}

计算n的阶乘(不使用递归):

public class RecursionTest
{
    public static void main(String[] args){
        int n = 4;
        int result = sum(n);
        System.out.println(result);
    }

    public static int sum(int n){
       int result = 1;
       for (int i=n; i>0; i--)
       {
           result *= i;
       }
       return result;
    }

}

使用递归:

public class RecursionTest
{
    public static void main(String[] args){
        int n = 4;
        int result = sum(n);
        System.out.println(result);
    }

    public static int sum(int n){
        if (n==1)
        {
            return 1;
        }
        return n*sum(n-1);
    }
}

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Java基础 方法执行内存分析-方法的重载机制-方法递归调用》 发布于2020-08-03

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

2 + 1 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册