/* 看板娘 */ canvas#live2dcanvas { border: 0 !important; left: 0; }

Java 方法调用 方法重载 方法递归

方法的调用

/*
    以下程序不使用”方法“,分析程序存在那些缺点?
    一下的代码都是完成int类型数据的和,相同的代码写了三遍。(只不过每一次参与求和的数据不通)
    代码没有得到重复使用
    应该在java语言当中有这样的一种机制:
        - 某个功能代码只需要写一边。
        - 要使用这个功能,只需要给这个功能传递具体的数据
        - 这个功能完成之后返回一个最终的结果,
        这样代码就可以重复利用了,提高代码复用性【这就是”方法“】
    使用这个方法我们称为”调用/invoke“
*/

public class MethodTest01
{
    public static void main(String[] args){
        // 需求1;请编写程序计算10和20的和,并将结果输出【功能:计算两个int类型数据的和】
        int a = 10;
        int b = 20;
        int c = a + b;
        System.out.println(a + " + " + b + " = " + c);

        // 需求2:请编写程序计算666和888的和,并将结果输出【功能:计算两个int类型数据的和】
        int x = 666;
        int y = 888;
        int z = x + y;
        System.out.println(x + " + " + y + " = " + z);

        // 需求3:请编写程序计算111和222的和,并将结果输出【功能:计算两个int类型数据的和】
        int m = 111;
        int n = 222;
        int e = m + n;
        System.out.println(m + " + " + n + " = " + e);

        // 以上的三个需求其实就是一个需求,这个需求是:计算两个int类型数据的和,功能相同。只不过每一次参与计算的具体数据不同。
    
    }
}
/*
    以下直接使用方法这种机制【这个例子不讲方法的语法】,分析程序的优点?
        代码得到了重复使用
    方法的本质是什么?
        方法就是一段代码片段,并且这段代码片段
        可以完成某个特定的功能,并且可以被重复的使用。
    方法,对应的英语档次:method
    方法在C语言中叫函数/Function

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

    方法体当中不能定义方法!!!!!

    方法体由java语句构成,方法体当中的代码遵守自上而下的顺序依次执行。
*/
public class MethodTest02
{
    // 类体
    public static void main(String[] args){
        // 计算两个int类型数据的和
        MethodTest.sumInt(10,20);
        MethodTest.sumInt(100,200);
        MethodTest.sumInt(111,222);

        
    }
    // 方法
    // 单独的定义一个方法
    // 该方法完成计算两个int类型数据的和,并且将结果输出
    public static void sumInt(int a,int b){
        int c = a + b;
        System.out.println(a + " + " + b + " = " + c);
    }
}
/*
    关于java语言当中的方法:
        1、方法怎么定义,语法结构;
            [修饰符列表]返回值类型 方法名(形式参数列表){
                方法体;
            }

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

                * 返回值类型可以是:
                    byte、short、int、long、float、double、boolean、char、String、void.......
                
                * 返回值类型若不是void,表示这个方法执行结束之后必须返回一个具体的数值。
                    当方法执行结束的时候没有返回任何数据的话编译器报错,怎么返回值呢,代码怎么写呢?
                    "return 值;",并且要求"值"的数据类型必须和"方法的返回值类型"一致,不然编译器报错.
                * 返回值类型是void的时候,在方法当中不能编写"return 值;" 这样的语句。但是要注意可以编写"return;"这样的语句
                * 只要带有return关键字的语句执行,return语句所在的方法结束。【不是JVM结束,是return所在方法结束】

            - 方法名:
                * 只要是合法的标识符就行
                * 方法名最好见名知意
                * 方法名最好是动词
                * 方法名首字母要求小写,后面每个单词首字母大写

            - 形式参数列表:简称形参
                * 形参是局部变量:int a; double b; float c; String s;....
                * 形参的个数可以是:0-N个
                * 多个形象之间用“逗号”隔开
                * 形象中起决定性作用的是形参的数据类型,形参的名字就是局部变量的名字。
                * 方法在调用的时候,实际给这个方法传递的真实数据被称为:实际参数,简称实参
                * 实参列表喝形参列表必须满足:
                    数量相同
                    类型对应相同

                    例如:
                        方法定义
                        public static int sum(int a,int b){  // (int a, int b)是形参列表
                        }
                        方法调用
                        sum("abc","def"); // 编译器报错
                        sum(10,20);  // (10,20)是实参列表


            - 方法体必须由大括号括起来,方法体当中的代码有顺序,遵循自上而下的循序依次执行
                并且方法体由java语句构成,每一个java语句以";"结尾

        3、方法怎么调用?
            - 方法只定义不去调用时不会执行的,只要在调用的时候才会执行。
            - 语法规则:【方法的修饰符列表当中有static】
                类名.方法名(实参列表); <这是一条java语句,表示调用某个类的某个方法,传递这样的实参。>

*/


// public 表示公开的
// class 表示定义类
// MethodTest是一个类名
public class MethodTest03    // 表示定义一个公开的类,起名MethodTest,由于是公开的类,所以源文件名必须, MethodTest.java
{
    // 类体
    // 类体中不能不直接编写java语句,除声明变量之外

    // 方法
    // public 表示公开的
    // static 表示静态的
    // void 表示方法执行结束之后不返回数据
    // main 是方法名:朱方法
    // (String[] agrs): 形式参数列表,其中String[] 是一种应用数据类型,args是一个局部变量的变量名
    // 所以以下只有args这个局部变量的变量名是随意的
    // 主方法就需要这样固定编写,这是程序的入口,【SUN规定的,必须这样写】

    
    public static void main(String[] args){

        // 这里的程序是一定会执行的
        // main方法是JVM负责调用,是一个入口位置
        // 从这里作为起点开始执行程序
        // 既然是这样,我们就可以在这里编写java语句来调用其它的方法
        // 调用MethodTest的sum方法,传递两个实参
        MethodTest.sum(10,20);    // (10,20)实参列表 【实际上执行到这里main方法暂停了,进入sum方法执行,sum方法执行结束之后表示main方法第一次调用结束】

        // 注意:方法体当中的代码是顺序的,遵循自上而下的顺序依次执行

        // 一个方法可以重复使用,重复调用
        int a = 100;
        MethodTest.sum(a,500); // (a,500)实参列表

        // 再次调用方法
        int k = 90;
        int f = 10;
        MethodTest.sum(k,f);  // (k,f)实参列表
    }


    // 自定义发放,不是程序的入口
    // 方法作用:计算两个int类型数据的和,不要求返回结果,但是要求将结果直接输出到控制台
    // 修饰符列表:public static
    // 返回值类型:void
    // 方法名:sum
    // 形式参数列表:(int x,int y)
    // 方法体:主要任务是求和之后输出计算结果
    public static void sum(int i,int j){    // (int i, int j)形参列表
        System.out.println(i + " + " + j + " = " + (i+j));
    }
}
/*
    方法的调用不一定在main方法当中,可以在其他方法当中
    只要是程序可以执行到的位置,都可以去调用其它方法
*/
public class MethodTest04
{

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

        // 调用doSome方法
        MethodTest.doSome();
    }

    // 主方法
    public static void main(String[] args){

        // 调用sum方法
        MethodTest.sum(1,2);
        System.out.println("hello world!");
    }

    public static void doSome(){
        System.out.println("do some!");
    }

}
/*
    方法调用的时候实参和形参要求个数对应相同,数据类型对应相同
    类型不痛的时候要求能够进行相应的自动类型转换
*/
public class MethodTest05
{

    public static void main(String[] args){

        // 编译错误:参数数量不通
        // MethodTest.sum();
        
        // 编译错误:实参和形参的类型不是对应相同的
        // MethodTest.sum(true,false);

        // 可以
        MethodTest.sum(10L,20L);

        // 存在自动类型转换:int--> long
        MethodTest.sum(10,20);

        // 编译错误:参数类型不是对应相同的
        // MethodTest.sum(3.0,20);

        // 可以
        MethodTest.sum((long)3.0,20);
    }

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

}
/*
    方法调用
        1、方法的修饰符列表当中有static关键字,完整的调用方式是:类名.方法名(实参列表);

        2、但是,有的时候“类名.”可以省略,什么情况下可以省略呢?
            m1(){
                m2();
            }
            m1方法和m2方法在同一个类体当中的时候,“类名.”可以省略不写
     3、建议在一个java源文件当中只定一个class,比较清晰,这里只是为了方便才在一个java源文件当中编写多个class,这种方式不要模仿
*/ public class MethodTest06 { public static void main(String[] args){ // 调用方法 MethodTest.m(); // 对于方法的修饰符列表当中有static关键字的:“类名.”可以省略不写吗? m(); // 调用其它类【不是本类中的】中的方法 A.doOther(); // 省略“类名.”试试 // 编译报错,“类名.”省略之后,默认从前类中找“doOther”方法,在当前类中该方法不存在。 // doOther(); } public static void m(){ System.out.println("m method execute!"); // 完整的方式 MethodTest.m2(); // 省略的方式 m2(); // 不想调用当前本类当中的m2方法,这个时候就必须添加“类名.”了。 A.m2(); } public static void m2(){ System.out.println("m2 execute!"); } } class A { public static void doOther(){ System.out.println("'A' s doOther method invoke!"); } public static void m2(){ System.out.println("'A' s m2 method execute!"); } }
/*
    分析以下程序的输出结果
        main begin
        m1 begin
        m2 begin
        m3 begin
        m3 over
        m2 over
        m1 over
        main over

        对于当前的程序来说:
            main方法最先被调用,main方法也是最后一个结束
            最后调用的方法是m3方法,该方法最先结束
        main方法结束之后,整个程序结束了【这句话只适合于当前所讲内容】

        不用刻意去记忆:
            只要记住方法中的代码是自上而下的循序依次执行即可。
            当前行的程序在没有结束的时候,下一行的代码是无法执行的。
*/
public class MethodTest07
{
    public static void main(String[] args){
        System.out.println("main begin");
        m1();    
        System.out.println("main over");
    }

    public static void m1(){
        System.out.println("m1 begin");
        m2();    
        System.out.println("m1 over");
    }

    public static void m2(){
        System.out.println("m2 begin");
        m3();    
        System.out.println("m2 over");
    }
    
    public static void m3(){
        System.out.println("m3 begin");
        System.out.println("m3 over");
    }

}
/*
    方法的返回值类型不是void的时候。
        1、返回值类型不是void的时候:要求方法必须保证百分百执行“return 值;”这样的语句来完成值返回
        没有这个语句编译器会报错。
        2、一个方法有返回值的时候,当我们调用这个方法的时候,方法返回了一个值,对于调用者来说,这个返回值可以选择接收,也可以选择不接受
        但是大部分情况下我们都是选择接收的
*/
public class MethodTest08
{
    public static void main(String[] args){
        // 调用方法
        divide(10,3); // 这里没有接收这个方法的返回数据
        
        // 这里接收一下方法执行的结束之后的返回值
        // 采用变量接收
        // 变量的数据类型需要和返回值的数据类型相同,或者可以自动类型转换,
        // boolean b = divide(10,3); // 编译报错,类型不兼容
        
        // 赋值运算符的右边先执行,将执行结果赋值左边的变量
        int i = divide(10,3);
        System.out.println(i);

        long x = divide(10,3);
        System.out.println(x);

        System.out.println(divide(10,3));


    }

    /*
        需求:
            请定义并实现一个方法,该方法可以计算两个int类型数据的商
            要求将最终的计算结果返回给调用者
    */
    // 编译报错:缺少返回语句
    /*
    public static int divide(int a,int b){
    }
    */

    // 编译报错:缺少返回值
    /*
    public static int divide(int a,int b){
        return;
    }
    */

    // 编译报错:方法定义的时候要求返回一个int类型,此时返回布尔类型,类型不兼容
    /*
    public static int divide(int a,int b){
        return true;
    }
    */


    // 可以:但是具体的方法体中编写的代码无法满足当前的需求
    /*
    public static int divide(int a,int b){
        return 1;
    }
    */

    


    public static int divide(int a,int b){
        int c = a / b;
        return c;
    }


}
/*
    深入return语句
        - 带有return关键字的java语句只要执行,所在的方法执行结束
        - 在”同一个作用域“当中,return语句下面不能编写任何代码,因为这些代码永远都执行不到,所以编译报错
    
*/
public class MethodTest09
{
    public static void main(String[] args){
        /*
            int retValue = m();
            System.out.println(retValue);
        */

        // 编译报错,调用方法,方法名后面有括号;
        // System.out.println(m);

        System.out.println(m());

    }

    // 编译报错:缺少返回语句,以下程序编译器认为无法百分百保证”return 1;“ 会执行。
    // 无法百分百保证”return 1;“会执行
    /*
    public static int m(){
        int a = 10;
        if(a > 3){
            return 1;
        }
    }
    */

    // 以下程序可以保证”return 1; 或 return 0;“执行,编译通过 
    /*
    public static int m(){
        int a = 10;
        if(a > 3){
            return 1;
        }else{
            return 0;
        }
    */

    // 可以,和以上方法完全相同
    /*
    public static int m(){
        int a = 10;
        if(a > 3){
            return 1;
        }
        return 0;
    }
    */

    /*
    public static int m(){
        int a = 10;
        if(a > 3){
            return 1;
            // 这里不能编写代码,编译报错,因为无法访问的语句
            // System.out.println("hello");
        }
        // 这里的代码可以执行到
        // System.out.println("hello");
        return 0;
    }
    */

    public static int m(){
        // return 10 > 3 ? 1 : 0;
        return 2 > 3 ? 1 : 0;
    }

}
/*
    在返回值类型是void的方法当中使用”return;“语句。
    ”return;“语句出现在返回值为void的方法当中主要是为了用来结束当前方法
*/
public class MethodTest10
{
    public static void main(String[] args){

        m();
        
        
        for(int i =10; i>0;i--){
            if(i == 2){
                return;  // 结束的是main方法
            }
            System.out.println("data: -->" + i);
        }
        System.out.println("Exeoute Here!");

        // 编译报错,返回值类型是void,不能返回值。
        // return 100;
        
    }

    // 编译错误:对于结果类型为空的方法,无法返回值
    /*
    public static void m(){
        return 10;
    }
    */

    /*
    public static void m(){
        return;
    }
    */

    public static void m(){
        for(int i = 0;i<10;i++){
            if(i==5){
                return;  // 不是终止for循环,终止的是m()方法。
                // break; // 终止的for循环
            }
            System.out.println("i -->" + i);
        }
        System.out.println("hello world");
    }

}
/*
    方法在执行过程当中,在JVM中的内存是如何分配的呢,内存是如何变化的?
        1、方法只定义,不调用,是不会执行的,并且在JVM中也不会给该方法分配运行所属的内存空间,
        只有在调用这个方法的时候,才会动态的给这个方法分配所属的内存空间
        
        2、在JVM内存划分上有这样三块主要的内存空间:(当然除了这三块之外还有其它的内存空间)
            - 方法区
            - 堆内存
            - 栈内存
        3、关于栈数据结构:
            - 栈:stack,是一种数据结构
            - 数据结构反应的是数据的存储形态
            - 数据结构是独立的学科,不属于任何编程语言的范畴,只不过在大多数编程语言当中要使用数据结构
            - 作为程序员需要提前精通:数据结构 + 算法【计算机专业必修一门课】
            - java程序员在不精通数据机构和算法的前提下,也可能进行java开发,因为java有一套庞大的类库支撑,别人写好了,直接用【JavaSE当中的集合章节使用了大量的数据结构】
            - 常用的数据结构:
                * 数组 * 队列 * 栈 * 链表 * 二叉树 * 哈希表/散列表...
        4、方法代码片段存在哪里?方法执行的时候执行过程内存在哪里分配?
            - 方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候,将其放到了方法区当中,所以JVM中的三块主要的内存空间中方法区内存最先有数据,存放了代码片段
            - 代码片段虽然在方法区内存当中只有一份,但是可以被重复调用。
                每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配。【栈内存中分配方法运行的所属内存空间】
        5、方法在调用的瞬间,会给该方法分配独立的内存空间,会在栈中发生压栈动作,
        方法执行结束之后,该方法分配的内存空间全部释放,此时发生弹栈动作。
            - 压栈:给方法分配内存
            - 弹栈:释放该方法的内存空间
        6、局部变量在”方法体“中声明。局部变量运行阶段内存在栈中分配。
            
*/



public class MethodTest
{
    public static void main(String[] args){
        m();

    }

    public static void m(){
        int i = 10;
    }

}

 

 

 
// 注意:在EditPlus当中,字体颜色为红色的表示一个类的名字,并且这个类是JavaSE类库中自带的。
// 我们自定义的类MethodTest,字体颜色是黑色,是标识符
// 其实JavaSE类库中自带的类,例如:String.class、System.class,这些类的类名也是标识符
// 只要是类名就一定是表示符


// 重点:方法调用的时候,在参数传递的时候,实际上传递的是变量中保存的那个“值”传过去的
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 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;
    }

}

/*
    画图依据:
        1、只要涉及到到参数传递的问题,传递的是变量中保存的值
        2、画图的时候,必须遵循“方法自上而下的顺序依次执行”这个原则
*/
// 分析以下程序的输出结果【画图分析】
// 画图应该这样画?
// 程序执行一步,在图上体现一步即可。
public class MethodTest
{
    public static void main(String[] args){
        int i = 10;
        method(i);
        System.out.println("main --> " + i);
    }

    public static int method(int i){
        i++;
        System.out.println("method --> " + i);
    }
}

方法重载

/*
    以下代码不使用“方法重载机制”,不适用overload,分析程序存在的缺点?
        1、sumInt,sumDouble,sumLong方法虽然功能不通,但是功能是相似的,都是求和。
        在以下程序当中功能相似的方法,分别起了三个不同的名字
        这对于程序员来说,调用方法的时候不方便,程序员需要记忆更多的方法,才能完成调用【不方便】
        2、代码不美观
    有没有这样的一种机制:
        功能虽然不同,但是“功能相似”的时候,有没有这样的一种机制,可以让程序员使用这些方法的时候就像在使用同一个方法一样
        这样程序员以后编写代码比较方便,也不需要记忆更多的方法名,代码也会很美观。

        有这种机制:方法重载机制/Overload
*/

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

        double result2 = sumDouble(1.0,2.0);
        System.out.println(result2);

        long result3 = sumLong(1L,2L);
        System.out.println(result3);

    
    }

    // 定义一个方法,可以计算两个int类型数据的和
    public static int sumInt(int a,int b){
        return a + b;
    }

    // 定义一个方法,可以计算两个double类型数据的和
    public static double sumDouble(double a,double b){
        return a + b;

    }
    // 定义一个方法,可以计算两个long类型数据的和
    public static long sumLong(long a,long b){
        return a + b;
    }

    // 最终希望达到的效果是:程序员在使用上面的相似的方法的时候,就像再用一个方法一样
    // Java支持这种机制【有些语言不支持,例如以后要学习的:Javascript】

}
/*
    该程序还是一个体验程序,体验一下方法重在的有点:
        - 程序员调用方法的时候,比较方便,虽然调用的是不通的方法,但是就感觉在使用一个方法一样
        不需要记忆更多的方法名
        - 代码美观
    前提:功能相似的时候,方法名可以相同
    但是,功能不通的时候,尽可能让这两个方法的名字不同
*/

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

        // 调用方法的时候就像在使用一个方法一样
        // 参数的类型不同,对应调用的方法不同,此时区分方法不再依靠方法名了,依靠的是参数的数据类型。
        System.out.println(sum(1,2));    
        System.out.println(sum(1.0,2.0));
        System.out.println(sum(100000000000L,200000000000L));
    
    }

    // 以下三个方法构成了方法重载机制
    public static int sum(int a,int b){
        System.out.println("int");
        return a + b;
    }
    public static long sum(long a,long b){
        System.out.println("long");
        return a + b;
    }
    public static double sum(double a,double b){
        System.out.println("double");
        return a + b;
    }
}
/*
    方法重载:
        1、方法重载又被称为:overload

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

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

        m2(1,2.0);
        m2(2.0,1);

        m3(10);
        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 x(){}

    public static int x(){}

    void y (){}

    public static void y(){}
    
    */
}
/*
    方法重载的具体应用
*/

public class OverloadTest
{
    public static void main(String[] args){
        U.p(10);
        U.p(false);
        U.p("abc");
        U.p(3.0);
    }

}


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

}

方法递归

/*
    关于方法的递归调用
        1、什么是递归?
            方法自身调用自身
            a(){
                a();
            }
        2、递归是很耗费栈内存的,递归算法可以不用的时候尽量别用

        3、以下程序运行的时候发生了这样的一个错误【不是异常,是错误Error】:
            java.lang.StackOverflowError
            栈内存溢出错误
            错误发生无法挽回,只有一个结果,就是JVM停止工作。
        4、递归必须有结束条件,没有结束条件一定会发生栈内存溢出错误
        5、递归即使有了结束条件,即使结束条件是正确的,也可能会发生栈内存溢出错误,因为递归的太深了
        注意:
            递归可以不使用尽量别用
            但是有些情况下该功能的实现必须依靠递归方式
*/

public class RecursionTest
{
    // 主方法
    public static void main(String[] args){
        
        System.out.println("main begin");
        // 调用doSome方法
        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 RecursionTest
{
    public static void main(String[] args){

        /*
        // 1~4的和
        int sum = 0;
        for(int i=1;i<=4;i++){
            sum += i;
        }
        System.out.println("sum = " + sum);

        */

        // 直接调用方法即可
        int n = 4;
        int retValue = sum(n);
        System.out.println(retValue);

        n = 10;
        retValue = sum(n);
        System.out.println(retValue);
    }

    // 单独的定义一个方法,这是一个独立的功能,可以完成1~N的求和
    public static int sum(int n){
        int result = 0;
        for(int i=0;i<=n;i++){
            result += i;
        }
        return result;
    }
}
/*
    使用递归计算1~N的求和
        1 + 2 + 3 + 4
        4 + 3 + 2 + 1 n的最初值是4,建议采用这种方式
*/

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

        // 1~4的和
        int n = 4;
        int retValue = sum(n);
        System.out.println(retValue);
    }

    public static int sum(int n){
        if (n == 1)
        {
            return 1;
        }
        return n + sum(n-1);  // 先运算sum(n-1),在跟n相加
        

    }
}

/*
    先不使用递归,计算N的阶乘
    5的阶乘
        5 * 4 * 3 * 2 * 1
*/


/*
public class RecursionTest
{
    public static void main(String[] args){


        int n = 5;
        int Net = method(n);
        System.out.println(Net);
    }

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


// 递归方式
// 不懂递归的,必须将以下的程序记住,因为面试题有出
public class RecursionTest
{
    public static void main(String[] args){


        int n = 5;
        int Net = method(n);
        System.out.println(Net);
    }

    public static int method(int n){
        if (n == 1){
            return 1;
        }
        return n * method(n-1);
    }
}
/*
    先不使用递归,计算N的阶乘
    5的阶乘
        5 * 4 * 3 * 2 * 1
*/


/*
public class RecursionTest
{
    public static void main(String[] args){


        int n = 5;
        int Net = method(n);
        System.out.println(Net);
    }

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


// 递归方式
// 不懂递归的,必须将以下的程序记住,因为面试题有出
public class RecursionTest
{
    public static void main(String[] args){


        int n = 5;
        int Net = method(n);
        System.out.println(Net);
    }

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

 

posted @ 2021-06-29 09:32  群临天下  阅读(242)  评论(0编辑  收藏  举报
/* 看板娘 */