007方法

7.1.1 章节目标
理解方法的本质以及作用;掌握方法的定义;掌握方法如何调用;理解栈数据结构;理解
方法执行过程中内存是如何变化的;掌握方法的重载机制;掌握方法递归算法。

知识框架:

 

 

7.1.2 方法的定义:

public class test1 {

    public static void main(String[] args) {
        test1.add(4,5);
    }
    public static void add(int x,int y) {                
        int z;
        z = x+y;
        System.out.println(x+"+"+y+"="+z);
    }

}

1:public static:修饰符列表,暂时先这么写

2:void:返回值类型,void表示没有返回值,有返回值的话写成byte,short,int,long,float,double,boolean,char,String,void 等

3:add:方法名,此项需要是合法的标识符,开发规范中要求方法名首字母小写,后面每个单词首字母大写,遵循驼峰命名方式,见名知意,例如:logingetUsername、findAllUser 等。

4:(int x,int y):形式参数列表,每一个形参都是局部变量

5:{ }  大括号里面的是方法体

6方法的调用:调用的语法格式为 类名.方法名(实际参数列表)

7:当在a()方法中调用b()方法时,若a,b方法在同一个类中,则类名可以省略。

 

7.1.3:有返回值的方法

 

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int a = 10;
        int b = 6;
        int i;
        i = sum(a,b);
        System.out.println(i);
        }
    public static int sum (int x,int y) {               //定义一个返回值类型为int 的方法
        int z = x+y;
        return z;
    }

 

注:

  1:写了有返回值就一定要有返回值,且返回值类型和定义返回值类型要相同,否则报错

  2:方法执行到return就会结束,所以,return后面不能有语句了,因为执行不到。

7.1.4 return 和 break的区别

  break是跳出循环,return是结束方法,二者不是一个概念

例:

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        x();
    }
    public static void x() {
        int i;
        for (i=0;i<=10;i++) {
            System.out.println(i);
            if (i == 5) {
                break;
            }
        }
        System.out.println("hello world");
    }

该程序运行结果为:

 

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        x();
    }
    public static void x() {
        int i;
        for (i=0;i<=10;i++) {
            System.out.println(i);
            if (i == 5) {
                return;                      //此处将break换成return
            }
        }
        System.out.println("hello world");
    }

运行结果为:

 

 

 由此可见,break是跳出循环,接着执行后面的语句,而return是直接结束方法,return后面的语句根本运行不到。

 

7.1.5 方法执行过程中内存的变化

 

 

上图是一张标准的 java 虚拟机内存结构图,目前我们只看其中的“栈”和“方法区”,其
它的后期研究,方法区中存储类的信息,或者也可以理解为代码片段,方法在执行过程中需要
的内存空间在栈中分配。java 程序开始执行的时候先通过类加载器子系统找到硬盘上的字节码
(class)文件,然后将其加载到 java 虚拟机的方法区当中,开始调用 main 方法,main 方法被调
用的瞬间,会给 main 方法在“栈”内存中分配所属的活动空间,此时发生压栈动作,main 方
法的活动空间处于栈底。

也就是说,方法只定义不去调用的话,只是把它的代码片段存储在方法区当中,java 虚拟
机是不会在栈内存当中给该方法分配活动空间的,只有在调用的瞬间,java 虚拟机才会在“栈
内存”当中给该方法分配活动空间,此时发生压栈动作,直到这个方法执行结束的时候,这个
方法在栈内存中所对应的活动空间就会释放掉,此时发生弹栈动作。由于栈的特点是先进后出,
所以最先调用的方法(最先压栈)一定是最后结束的(最后弹栈)。比如:main 方法最先被
调用,那么它一定是最后一个结束的。换句话说:main 方法结束了,程序也就结束了(目前
来说是这样)。
接下来我们来看一段代码,同时画出内存结构图,以及使用文字描述该程序的内存变化:

public class test1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        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");
        System.out.println("m2 over");
    }
    
}

执行结果为

 

   

7.3 方法重载/overload

方法重载(overload)是指在一个类中定义多个同名的方法,
但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java 编译器能通过检
查调用的方法的参数类型和个数选择一个恰当的方法。方法重载通常用于创建完成一组任务相
似但参数的类型或参数的个数不同的方法。调用方法时通过传递给它们的不同个数和类型的实
参来决定具体使用哪个方法。

什么情况下我们考虑使用方法重载呢?在同一个类当中,如果多个功能是相似的,可以考
虑将它们的方法名定义的一致,使用方法重载机制,这样便于程序员的调用,以及代码美观,
但相反,如果两个方法所完成的功能完全不同,那么方法名也一定要不一样,这样才是合理的。
代码满足什么条件的时候构成方法重载呢?满足以下三个条件:
① 在同一个类当中。
② 方法名相同。
③ 参数列表不同:个数不同算不同,顺序不同算不同,类型不同也算不同。

Tips:每次输入System.out.println(); 是不是很烦,学过方法的重载之后是不是可以自己建一个方法改进一下

 

7.4 方法递归

1:什么是方法递归?

先来看一个程序

 

public class test1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        m();
    }
    public static void m() {
        System.out.println("m begin");
        m();
        System.out.println("m over");
    }
}

运行结果为:

 

 

我们可以看到以上代码的执行过程中,一直输出“m begin”,“m over”一次也没有输出,
直到最终发生了错误:java.lang.StackOverflowError,这个错误是栈内存溢出错误,错误发生后,
JVM 退出了,程序结束了。

实际上以上代码在 m()方法执行过程中又调用了 m()方法,方法自身调用自身(经典我调我自己),这就是方
法递归调用。

注意:

  1:在使用递归时,必须有结束条件,否则就会造成无终止压栈,最终导致栈内存溢出。

  2:一个递归有合法结束条件时,由于递归太深,还没达到结束条件栈内存就溢出了,这也是有可能的,所以,在实际开发中我们尽可能的用循环代替递归算法。

posted @ 2021-04-19 10:00  南昌故郡  阅读(56)  评论(0)    收藏  举报