首先要知道java方法参数是怎么传递的
java方法参数的传递分为两种
1.基本类型的传递:
java方法中参数的传递对于基本类型来说是传递基本类型的值,也就是我们所说的传值
2.对象的传递:
对于对象的传递java中是传递对象的引用,也就是传递对象的地址,也就是传址(有的也说这个也是传值,只不过这个值包装了对象的地址原理其实是一样的)
java方法的调用是在方法栈中运行,分为方法入栈、出栈、压栈、弹栈、执行代码五个部分。
入栈:当运行方法的时候方法就会进入方法栈接着执行此方法。
出栈:当方法运行完毕之后方法就会移除方法栈
压栈与弹栈:当一个方法在运行当中调用了另一个方法,那么此方法就会压栈,被调用的方法就会入栈开始执行,当被调用的方法执行完毕出栈后,压栈的方法就会弹栈,接着执行后面的代码。
光说没用,看看例子吧
例1:
public static void main(String[] args) {
int i = 5;
change(i);
System.out.println(i); //result 5
}
public static void change(int i) {
i = 500;
}
分三个阶段分析:
阶段一:main方法入栈开始执行代码,在栈中初始化一个基本变量int i=5,执行到change方法,main方法压栈。
阶段二:change方法入栈开始执行代码,这里要注意,当执行change方法的时候是在方法栈中重新开辟一块内存来执行此方法;此方法传递了一个参数int i = 5,在内存中是初始化一个变量并赋值为5接着执行 i = 500,重新给变量i赋值为500,然后方法执行完毕,chang方法出栈,这个时候,为执行chang方法开辟的那块内存就会自动销毁。
阶段三:change方法执行完出栈,main方法弹栈,接着执行后面的代码,这里注意了, main方法中的变量i虽然传递给chang方法重新赋值,但只是在chang方法内部赋了值,当chang方法执行完出栈了,内存自动销毁,也就是说,main方法中变量i并没有被赋上值还是原来的5,所以最后打印出5,main方法出栈,执行main方法的那块内存销毁。
例2:
public static void main(String[] args) {
Person person = new Person();
person.age = 18;
changeAge(person);
System.out.println(person.age); //result 25
}
public static void changeAge(Person person) {
person.age = 25;
}
class Person {
int age;
}
分析:
同样是三个阶段:
阶段一:main方法入栈开始执行代码,初始化一个Person对象(这里是在堆中new一个Person),并给person对象的age属性赋值为18。
阶段 二:changeAge方法入栈开始执行代码,这里要注意,当执行change方法的时候是在方法栈中重新开辟一块内存来执行此方法;此方法传递了一个Person对象引用(即堆中new出来的person对象的地址),接着重新给person对象中的age属性赋值为25方法执行完毕,chang方法出栈,这个时候,为执行chang方法开辟的那块内存就会自动销毁,但是Person对象是在堆内存中,并没有销毁,也就是说现在person对象的age属性的值为25。
阶 段三:change方法执行完出栈,main方法弹栈,接着执行后面的代码,所以我们会看到打印出Person对象的age属性的值是25,方法执行完毕main方法出栈,执行main方法的那块内存销毁,这个时候就没有任何一个对象的引用指向堆内存中的person对象了,java虚拟机会通过finalize方法清理没有引用指向的对象进行垃圾回收。
总结:
java方法的运行主要有三点
1:java方法的参数的传递对于基本类型则是传递变量的值,对于对象则是传递对象的应用(即对象的地址)
2:java方法是在方法栈中运行的主要分为五个部分:入栈、出栈、压栈、弹栈、执行代码
3:java每执行一个方法都会在方法栈中开辟一个新的内存,且当方法执行完毕这块内存会自动释放