编程语言基础《4》
3.0方法初步
1方法的基础语法
1基本概述
1,方法概念:一段代码具有复用性,并且能完成某个特定的功能,这就是方法。
2,调用(invoke):使用这个方法叫做调用。
3,方法定义规则:定义在类体中,一个类可以定义多个方法,方法定义位置没有先后顺序之分。
4,方法体中不能再定义方法。
5,方法体中的代码遵守自上而下的顺序依次执行。
2方法的语法结构
1 [修饰符列表] 返回值类型 方法名(形式参数列表){ 2 方法体; 3 }
3 关于修饰符列表
1 可选项,不是必须的。
2 目前写成:public static
3 方法的修饰符列表中有static关键字的话,怎么调用这个方法?
类名.方法名(实际参数列表); 【或者叫做类名的方法名】
4 返回值类型
1 什么是返回值?
一个方法可以完成某个特定的功能,这个功能结束后大多数都是需要返回最终执行结果的,
这个结果可能是一个具体存在的数据,这个数据就是返回值。
2 返回值类型?
返回值是一个具体存在的数据,数据都是有类型的,此时需要指定返回值的具体类型。
3 返回值类型可以指定哪些类型?
1 java任意一种类型都可以,包括基本数据类型和引用数据类型。
2 也有可能方法执行结束后不返回任何数据,那么这个方法在返回值类型位置必须编写关键字:void
3 返回值如果不是void,表示这个方法执行结束后必须返回一个具体的数值。否则,编译器报错。
4 返回值格式:return 值; 要求:该“值”的数据类型与定义的“方法的返回值类型”一致。否则编译器报错。
5 如果返回值和规定的返回值类型不匹配,会报编译错误。
6 返回值类型是“void”的时候,方法体中不能编写“return 值;” 这样的语句。但可以编写“return;”这样的语句。
7 只要带有return关键字的语句执行,return语句所在的方法就会结束。所以,return表示强制结束方法执行。
5 方法名
1 只要是合法的标识符就行
2 方法名最好见名知意
3 方法名最好是动词
4 方法名首字母要求小写,后面每个单词首字母大写
6 形式参数列表(形参)
1 形参是局部变量
2 形参的个数可以是:0 - N个
3 多个形参之间用“逗号”隔开
4 形参中起决定性作用的是形参的数据类型,形参名字就是局部变量的名字
5 方法在调用的时候,实际给这个方法传递的真实数据叫实际参数(实参)
7 方法体
方法体必须由大括号括起来,方法体中的代码有顺序,遵循自上而下的顺序依次执行。
8 方法怎么调用
1,方法只定义不去调用是不会执行的,只有在调用的时候才会执行。
2,例如,类名.方法名(实际参数); 表示:调用某个类的某个方法,传递这样的实参。
9 main主方法解释
public static void main(String[] args){ }
public:公开的
static:静态的
void:方法执行结束后不返回任何数据
main:方法名,主方法。
(String[] args):形参列表,String[]是一种引用数据类型,args是局部变量的变量名。
10方法的调用
1 方法的调用不一定在main方法中,也可以在其他方法中。只要是程序可以执行到的位置,都可以去调用其它方法。
2 示例:
1 public class MethodTest{ 分析:程序执行过程 2 public static void sumInt(int a,int b){ 1,先进入main方法,执行sumInt方法 3 int c = a + b; 2,再进入sumInt方法,执行运算过程 4 System.out.println(a + "+" + b + "=" + c ); 3,根据代码顺序,进入doSome方法,执行输出语句 5 // 调用doSome方法 4,回到main方法,输出Hello World 6 MethodTest.doSome(); 5,至此,程序全部执行完毕。 7 } 8 // 主方法,程序的入口 9 public static void main(String[] args){ 10 sumInt(5,15); 11 System.out.println("Hello World!"); 12 } 13 public static void doSome(){ 14 System.out.println("do some!"); 15 } 16 }
3,方法参数的要求
1 参数数量不同
2 实参和形参的数据类型不匹配
3 类型不同的时候要求能够进行相应的自动类型转换(小的转大的)
4,调用方法的书写方式
1 在同一个类中,对于方法的修饰符列表中有static关键字的:调用方法时【类名.】可以省略不写
2 调用其他类(不是本类)中的方法,“类名.”不能省略。
11方法的返回值类型不是void的时候
1 要求:方法必须百分百的执行“return 值;”这样的语句来完成值得返回。
2 一个方法有返回值的时候,当我们调用这个方法的时候,方法返回了一个值。
对于调用者来说,这个返回值可以选择接收,也可以选择不接收。
3 一般采用变量接收,变量的数据类型和返回值的数据类型相同,
或者可以自动类型转换:long x = divide(10,3);
4 示例
1 public class MethodTest{ 2 // 主方法,程序的入口 3 public static void main(String[] args){ 4 int i = divide(10,2); 5 System.out.println(i); 6 } 7 public static int divide(int a,int b){ 8 int c = a / b; 9 return c; 10 } 11 }
12深入return语句
1,带有return关键字的语句只要执行,所在的方法执行结束。
2,在“同一个作用域”中,return语句下面不能编写任何代码,因为它们永远执行不到。
3,对于结果类型为空(void)的方法,无法返回值。即不能写【return 值;】
但是可以写【return;】目的是终止当前方法的执行。
3,示例


2方法执行内存分析
1内存图

2栈内存图

3方法在执行过程中,JVM是如何分配内存的?
1,方法如果只是定义了没有调用,JVM虚拟机是不会给该方法分配运行内存的。
2,在JVM内存划分上有三块主要的内存空间
* 方法区内存
* 堆内存
* 栈内存
3 方法被调用的时候,会在栈中给方法分配独立的内存空间,此时发生压栈动作;
方法执行结束后,给方法分配的内存空间全部释放掉,此时发生弹栈动作。
压栈:给方法分配内存
弹栈:释放该方法的内存空间
4,局部变量在“方法体”中声明,局部变量在运行阶段在栈中分配内存。
5,方法在调用的时候,在传递参数时,实际上传递的是变量中保存的那个“值”。
4栈数据结构
* 栈:stack,是一种数据结构
* 数据结构反应的是数据的存储形态
* 常见的数据结构:数组、队列、栈、链表、二叉树、哈希表/散列表....
5方法代码片段存在哪里?
1 方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候,将其放到了方法区中。
所以,JVM中的三块主要的内存空间中,方法区最先有数据。
2 代码片段虽然在方法区中只有一份,但可以被反复调用。每次调用方法时,都会在栈内存中分配独立的活动场所。
3方法的重载机制
1,方法重载的优点:调用方法的时候就像在使用一个方法一样,不需要记忆过多的方法名。
2,方法重载称为:overload。
3,什么时候使用方法重载?
* 功能相似的时候,方法名可以相同。
* 功能不同的时候,尽可能让这两个方法的名字不同。
4,方法重载的条件是什么?
* 在同一个类中
* 方法名相同
* 参数列表不同
* 数量不同
* 顺序不同
* 类型不同
5,方法重载和什么有关系?和什么没关系。
* 方法重载和方法名+数据类型有关系
* 方法重载和返回值类型没有关系
* 方法重载和修饰符列表没有关系
6,方法重载应用
1 写一段具有某种功能的java代码
比如,将System.println();方法使用重载的形式写一遍。
2 封装为class文件.
3 假如你将要写的java文件和封装好的.class文件在同一目录下,直接使用类名.方法名就可以了。
3.1递归问题
1方法的递归调用
1递归简单示例
1 public class MethodTest{ 分析: 2 // 主方法,程序的入口 1 该递归程序会一直执行下去:doSome begin 3 public static void main(String[] args){ 4 System.out.println("main begin"); 5 doSome(); 6 System.out.println("main end"); 7 } 8 public static void doSome(){ 9 System.out.println("doSome begin"); 10 doSome(); 11 System.out.println("doSome end"); 12 } 13 }
2,什么是递归:方法自己调用自己。
3,递归是很耗费栈内存的,递归算法能不用尽量别用。
因为它不断的调用自身,每调用一次就会开辟一块栈内存,然后在内存中又调用自己,又得开辟一块内存,如此循环往复,永不结束,最终导致栈内存溢出错误,不是异常,是错误。错误发生无法挽回,结果只有一个:JVM停止工作。
4,递归一定要有结束条件,不然会导致栈内存溢出错误。
5,递归即使有结束条件,并且该条件是正确的,也可能发生栈内存溢出错误,因为递归太深了。
2示例
1,使用递归计算1--4的累加和
1 public class MethodTest{ 分析: 2 // 主方法,程序的入口 1,最终要的就是指定结束条件:if(n==1) return 1; 3 public static void main(String[] args){ 2,递归体:通过分析找到规律,n + sum(n-1) 4 // 1- 4的和 1,main:n == 4 sum4:4 + sum(4-1) 5 // 4 + 3 + 2 + 1 2,sum3:3 + sum(3-1) 6 int n = 4; 3,sum2:2 + sum(2-1) 7 int retValue = sum(n); 4,sum1:符合n==1的条件,所以返回值是1 8 System.out.println(retValue); 5,sum2:2+1=3 9 } 6,sum3:3+3=6 10 public static int sum(int n){ 7,sum4:4+6=10 11 if(n == 1){ 3,把10这个结果赋值给变量retValue。输出打印这个变量。 12 return 1; 13 } 14 return n + sum(n -1); 15 } 16 }
2,使用递归的方式求5的阶乘
1 public class MethodTest{ 2 // 使用递归方式求5的阶乘 3 public static void main(String[] args){ 4 int n = 5; 5 int retValue = method(n); 6 System.out.println(retValue); 7 } 8 public static int method(int n){ 9 if(n == 1){ 10 return 1; 11 } 12 return n * method(n -1); 13 } 14 }
3递归示意图


浙公网安备 33010602011771号