方法传参机制
1、引用传递:栈调用的方法所指向的数据空间,和主方法里指向的数据空间是一样的。所以class B里对数组的修改,会影响到主方法里的数组。
结论:引用类型(即对象、数组)传递的是地址(传递也是值,但值是地址),可以通过形参影响实参!
练习1: 在B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来数组是否变化。
public class MethodParameter {
public static void main(String[] args) {
B b = new B();
int[] arr = {1,2,3};//数组是引用类型,有地址,会指向堆空间
b.test100(arr);//只要调用方法,就会产生新栈
//引用类型不是值拷贝,传递的是地址,
// 所以新栈test100里的arr也指向main里的arr的地址,在堆空间里是同一个。
System.out.println("\n"+"main的arr数组");
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
class B{
// 在B类中编写一个方法test100,可以接收一个数组
//在方法中修改该数组,看看原来数组是否变化
public void test100(int[] arr){
arr[0] = 200;//修改元素
//遍历数组
System.out.println("test100的arr数组");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
练习2: 在B类中编写一个test200,可以接收一个Person(age,sal)对象,在方法中修改对象属性,看看原来的对象是否变化。
public class MethodParameter {
public static void main(String[] args) {
//测试
B b = new B();
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);//实质:把p对象的地址赋给了test200作形参p,共享一个数据空间。
System.out.println("main的p.age=" + p.age);
}
}
//在B类中编写一个test200,可以接收一个Person(age,sal)对象,
// 在方法中修改对象属性,看看原来的对象是否变化。
class Person {
String name;
int age;
}
class B {
public void test200(Person p) {
p.age = 10000;//修改对象属性
}
// 在B类中编写一个方法test100,可以接收一个数组
//在方法中修改该数组,看看原来数组是否变化
public void test100(int[] arr) {
arr[0] = 200;//修改元素
//遍历数组
System.out.println("test100的arr数组");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
测试题1:练习2中class B中test200执行p = null;产生的结果是——
public class MethodParameter {
public static void main(String[] args) {
//测试
B b = new B();
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);//实质:把p对象的地址赋给了test200作形参p,共享一个数据空间。
System.out.println("main的p.age=" + p.age);
}
}
//在B类中编写一个test200,可以接收一个Person(age,sal)对象,
// 在方法中修改对象属性,看看原来的对象是否变化。
class Person {
String name;
int age;
}
class B {
public void test200(Person p) {
//错误哦:p.age = 10000;//修改对象属性
p = null;//形参地址置空,实参还是原来的地址。不会改变main栈。原先指向你,现在不指向你了!
//现在指向空的地方,与你无关系了。我把我自己置空,没有办法把你置空。
}
}
测试题2:练习2中class B中test200执行p = new Person…产生的结果是——
public class MethodParameter {
public static void main(String[] args) {
//测试
B b = new B();
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);//实质:把p对象的地址赋给了test200作形参p,共享一个数据空间。
System.out.println("main的p.age=" + p.age);//找的仍然是main方法里的p
}
}
//在B类中编写一个test200,可以接收一个Person(age,sal)对象,
// 在方法中修改对象属性,看看原来的对象是否变化。
class Person {
String name;
int age;
}
class B {
public void test200(Person p) {
p = new Person();//在堆空间里又产生一个新的人对象,此时不指向main里p的地址。
//指向新的人对象的地址。
p.name = "Tom";
p.age = 99;
//尴尬的是:test200里创建了对象,也赋值了,但是直接走了没有用到,所以这个对象会被当做一个垃圾被回收。
//相当于在test200里创建了个局部变量p,弄完没有用就返回了,返回后这个就变成了没有任何变量引用的对象,就会成为垃圾被回收。
}
}