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:一个递归有合法结束条件时,由于递归太深,还没达到结束条件栈内存就溢出了,这也是有可能的,所以,在实际开发中我们尽可能的用循环代替递归算法。
浙公网安备 33010602011771号