方法调用机制
Person p1 = new Person();
int res = p1.getSum(10,20);
System.out.println("值="+res);
public int getSum(int num1,int num2){
int res = num1 + num2;
return res;
}
1. 当程序执行到方法时,会在栈里单独开辟一个空间(这也是为什么swap无法使用的原因)。
2. 当方法执行完毕,或者执行到return语句时,就会返回。
3. 返回到调用方法的地方。
4. 返回后继续执行方法后面的代码。
5. 当main方法执行完毕,整个程序退出。
方法调用细节
1. 同一个类中的方法调用
2. 跨类中 A类调用B类的方法
需要通过新建对象,用 对象名.方法名(参数) 进行调用。(注意这种跨类调用要符合访问修饰符的限制)
class first {
public void Hi() {
System.out.print("Hi!");
}
}
class second {
public void useA() {
first a = new first(); //构建一个对象
a.Hi(); //调用跨类的方法
}
}
3. 传递的参数为引用类型详解
public class Practice {
public static void main(String[] args) {
Person a = new Person();
a.age = 20; //初始化的属性值
Test p = new Test();
p.test01(a);
System.out.print(a.age);
}
}
class Person {
int age;
String name;
}
对象的属性修改为另一个值:
class Test {
public void test01(Person b) {
//传递一个对象(引用传递)
b.age = 100000; //修改对象的属性
}
}
让对象指向null:
class Test {
public void test01(Person b) {
b = null; //对象指向null
}
}
初始化对象:
class Test {
public void test01(Person b) {
b = new Person();
}
}
可以发现,当传入一个对象时,只有修改对象属性值才会生效,如果把对象指向null,或者让对象指向一个刚new的新对象,对原来的对象并没有什么影响。这是为什么呢?这里就需要考虑到方法调用机制了。
当调用test方法,传入一个对象时,实际上在栈里新开辟了一个空间,在这个空间里创建了一个指向Person对象的新指针 b(参考调用机制),接收传入对象的地址(实际上传入的是地址,注意与C++的引用不同,可以说类似于指针)。
然后 b 就指向堆区域的实际对象了,对 b 的属性进行修改,其实就是对实际对象进行修改。但是,如果把null赋给b,实际上只是 b 指向了null,对主函数声明的 a 没有任何影响,new也是同理,只有 b 指向了一个新的对象,而主函数声明的 a 仍然指向原来的对象。因此,最后输出的都是20。
4. 修改String属性的理解
public static void main(String[] args) {
Person a = new Person();
Person b = new Person();
a.name = "milan";
b.name = "milan";
System.out.println(a.name);
System.out.println(b.name);
b.name = "shang";
System.out.println("==========");
System.out.println(a.name);
System.out.println(b.name);
}
已知String是一个类,因此Person的name属性也是存放的地址。根据上面的代码,a和b的名字相同,name都指向”milan”。这时候修改b的name为”shang”,那么a的name属性会不会发生变化?
是不会的。修改b的name的实质,并不是修改对应地址的内容,而是重新开辟了一块区域,里面的内容是”shang”,然后把这个地址赋给b.name,对原先”milan”所在区域没有任何影响。
递归调用机制
1. 输出递归
class Person {
public void test(int n) {
if(n>2)
test(n-1); //递归调用
System.out.println("n的值为: " + n);
}
}
//主函数 Person a = new Person(); a.test(4);
由于只是值传递,因此每一层中n的值并不会被下一层改变,最终结果为:
2. 阶乘
public int factorial(int n) {
//假设n为5
if (n == 1) {
return 1;
} else {
return factorial(n - 1) * n;
}
}