chapter4:方法
1 java方法基础介绍
1.1 方法的概念及命名规范
● 概念
- java中的方法是指包含于java类或对象中用于解决某一类问题的java语句块,类似于其他语言中的函数。
● 命名规范
- 小驼峰命名法,即方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符,如addPerson。
- 下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test_,例如 testPop_emptyStack。
1.2 方法的语法格式
[修饰符列表] 返回值类型 方法名(形式参数类型 参数名){
...
方法体
...
return 返回值;
}
名词 | 描述 |
---|---|
修饰符列表 | 可选,包括public、protected、default、private,abstract,static,synchronized,其中,public,protected,private不能同时存在 |
返回值类型 | 任意一种类型都可以,包括基本数据类型和所有的引用数据类型 |
方法名 | 采用小驼峰命名法,遵循“见名知义”原则 |
形式参数列表 | 参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。 |
1.3 方法的调用
- 无参:
方法名()。例如:doSome() - 有参:
方法名(实参1,实参2,…)。例如:doSome(a,b,…)
1.4 方法的注意事项
- 方法不能嵌套定义
- 方法的定义不分先后,定义后,不调用不会执行,也不会为该方法分配 运行所属 的内存空间。
- 如果方法没有返回值类型,需要使用void关键字,同时方法体中可以省略return
- 如果方法有返回值类型,方法体中必须写return数据值。
1.5 JVM内存机制
-
在JVM内存划分上有这样三块主要的内存空间(当然除了这三块还有其他的)
- 方法区内存
- 堆内存
- 栈内存
-
图示:
-
方法代码片段属于.class字节码文件的一部分,字节码文件在类型加载的时候,将其放到了方法区当中。所以JVM中的三块主要的内存空间中方法区内存最先有数据。每次调用这个方法的时候,需要给该方法分配独立的运行空间,在栈内存中分配 (注意:栈内存中分配方法运行的所属内存空间)
-
方法在被调用的时候,会给该方法分配内存空间,会在栈中发生压栈动作,方法执行结束后,会将为该方法分配的内存空间全部释放,此时发生弹栈动作。
◎ 压栈:给方法分配内存
◎ 弹栈:释放该方法的内存空间 -
局部变量在“方法体”中声明,局部变量运行阶段
2 方法的重载机制
2.1 重载的概念
- 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
2.2 重载的特点
- 与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数,参数类型,参数顺序)。在方法调用时根据参数列表来分别调用不同的方法。
2.3 重载示例
- 不使用重载机制:
package java方法.方法重载;
public class OverLoadDemo01 {
public static void main(String[] args) {
System.out.println(sumInt(1,2));
System.out.println(sumLong(1,2));
System.out.println(sumDouble(1.0,2.0));
}
public static int sumInt(int a,int b) {
return a+b;
}
public static long sumLong(long a,long b) {
return a+b;
}
public static double sumDouble(double a,double b) {
return a+b;
}
}
- 以上代码不使用“方法重载机制”,程序存在以下缺点:
- sumInt,sumLong,sumDouble方法最燃功能不同,但是功能相似,都是求和,在以下程序当中功能相似的方法,分别起了三个不同的名字,
这对于程序员来说,调用方法的时候非常不方便,程序员需要记住更多的方法名,才能完成调用【不方便】 - 代码不美观
- 使用重载机制:
public class OverLoadDemo01 {
public static void main(String[] args) {
System.out.println(sum(1,2));
System.out.println(sum(1L,2L));
System.out.println(sum(1.0,2.0));
}
public static int sum(int a,int b) {
return a+b;
}
public static long sum(long a,long b) {
return a+b;
}
public static double sum(double a,double b) {
return a+b;
}
}
3 方法的递归调用
3.1 递归调用的概念
- 递归调用简单来说就是自己调用自己,适用于方法中运算的主体不变,但运行的方法参数会发生变化。
3.2 递归调用的注意事项
- 递归一定要有出口,否则会发生栈内存溢出
- 递归次数不宜过多,如果次数过多,由于栈内存的空间有限,也可能会发生栈内存溢出。
- 构造方法,禁止递归
3.3 递归调用的内存分析
3.4 递归调用示例
package java方法.方法的递归调用;
/*
1.计算1到n的和
2.计算阶乘
3.计算斐波那契数列
*/
public class DiGuiDemo01 {
public static void main(String[] args) {
System.out.println(getSum(10));
System.out.println(getFactorial(4));
System.out.println(getFiboracci(12));
}
// 1.计算1到n的和
public static int getSum(int n){
if(n==1){
return 1;
}
return n+getSum(n-1);
}
// 2.计算阶乘
public static int getFactorial(int n){
if(n==1){
return 1;
}
return n*getFactorial(n-1);
}
// 3.计算菲波那切数列 1 1 2 3 5 8 13 21 34 55 89 144……
public static int getFiboracci(int n){
if(n==2 || n==1){
return 1;
}
return getFiboracci(n-1)+getFiboracci(n-2);
}
}
4 方法的参数传递
示例:
- User.java
public class User {
//实例变量
int age;
//构造方法
public User(int i){
age = i;
}
}
- Test.java
public class Test {
public static void main(String[] args) {
User u = new User(22);
//User u = 0x1234
//传递u给add方法的时候,实际上传递的是u变量中保存的值,而这个值就是java对象的内存地址
add(u);
System.out.println("main-->"+u.age);
}
public static void add(User u){
u.age++;
System.out.println("add-->"+u.age);
}
}
程序执行结果:
-
java参数传递内存机理
结论:
-
方法调用的时候,涉及到参数传递的问题,传递的时候,java只遵循一种语法机制,就是将变量中保存的“值”传递过去了,只不过有的时候,这个值是一个字面值10,有的时候这个值是另一个java对象的内存地址0x1234。