先让我们猜一下如下代码的输出结果~
public class MethodParameter01 {
//编写一个 main 方法
public static void main(String[] args) {
int a = 10;
int b = 20;
//创建 A 对象 名字 obj
A obj = new A();
obj.swap(a,b); //调用swap方法
System.out.println("main 方法\na=" + a + "\tb=" +b);
}
}
class A {
public void swap(int a, int b){
System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);
//完成 a 和 b 的交换
int temp = a;
a = b;
b = temp;
System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);
}
}
你做对了吗?请看图
栈存放基本数据类型:byte、short、int、long、float、double、char、boolean
堆存放引用数据类型:数组、对象、String
方法区里面有常量池:也是存放引用数据类型
结论:基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参!
看一个案例
public class MethodParameter02 {
//编写一个 main 方法
public static void main(String[] args) {
//测试1
B b = new B();
// int[] arr = {1, 2, 3};
// b.test100(arr);//调用方法
// System.out.println(" main 的 arr 数组 ");
// //遍历数组
// for(int i = 0; i < arr.length; i++) {
// System.out.print(arr[i] + "\t");
// }
// System.out.println();
//测试2
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);
//测试题, 如果 test200 执行的是 p = null ,下面的结果是 10
//测试题, 如果 test200 执行的是 p = new Person();..., 下面输出的是 10
System.out.println("main 的 p.age=" + p.age);//10000
}
}
class Person {
String name;
int age;
}
class B {
public void test200(Person p) {
//p.age = 10000; //修改对象属性
//思考
//p = new Person();
//p.name = "tom";
//p.age = 99;
//思考
p = null; //即 指向null地址,不改变main栈的指向堆地址中数据
}
//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");
}
System.out.println();
}
}
结果如下: 会变化!
你猜对了吗?看图
B 类中编写一个方法 test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
变化。因为引用数据类型传参,可以看做两个变量指向同一个地址。
B 类中编写一个方法 test200,接收Person类,在方法中将对象p指向 null,看看原来的数组是否变化?
答:不变化,虽然两个对象指向同一个地址,但是在test200方法中 p -> null,即失效,该图只有main栈中的 p -> 地址。
结论:引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!