首先我们需要明确一些概念
一、在java当中形参和实参分别是指:
形参:用来接收调用该方法时传递的参数。只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间
实参:传递给被调用方法的值,预先创建并赋予确定值
即方法中定义的入参为形参,而传递给方法的对象或值就是实参
二、java传值和传引用的区别
实际上在java中所有的参数都是传值的,引用符号&的传递是C++中才有的
不过对于基本类型(byte–short–int–long–float–double–boolean–char)的变量总是按值传递,即将实参值复制一份给形参,而对于对象来说,不是将对象本身传递给方法,而是将对象的的引用或者说对象的首地址当做值传递给方法,引用本身是按值传递的,对于String、Integer、Long,数组等,这些也都相当于对象,因此传参时也相当于是传引用的值
从下面的地址可以清晰的看出上述区别
public class Test {
public static void main(String[] args) {
/**
1.调用String的valueOf方法,在栈内存上创建引用变量str(实参),
在常量池中获取hello字符串,有则str指向该字符串,无则在常量池中创建该字符串后实参str引用指向该对象
2.调用chang方法,将str(实参)引用传递给change方法的str(形参),此时两个str引用都是指向常量池中的hello字符串,
执行change方法体,将str(形参)所指向的引用改为常量池中的changed,退出方法后销毁str(形参)
3.打印str(实参)的值,此时由于str(实参)的引用地址未变仍指向hello,故打印hello
*/
String str = "hello";
change(str);
System.out.println(str);
/**
* 1.创建一个引用变量a(实参)指向堆内存中的A对象,并创建一个形参指向hello字符串,然后在A的构造方法中赋值给str,
* 此时堆内存中的A对象中包含一个在栈内存的str引用变量,str则指向常量池中的hello字符串
* 2.执行change方法,将a(实参)的引用赋值给a(形参),执行方法体后,a(形参)对象引用指向地址变为堆内存中一个新的A对象,
* 退出方法后销毁a(形参)
* 3.打印a(实参)所引用的str对象,此时a(实参)对应的A对象中的str并未发生改变,故打印hello
*/
A a = new A("hello");
change(a);
System.out.println(a.str);
/**
* 1.创建一个引用变量a1(实参)指向堆内存中的A对象,并创建一个形参指向hello字符串,然后在A的构造方法中赋值给str,
* 此时堆内存中的A对象中包含一个在栈内存的str引用变量,str则指向常量池中的hello字符串
* 2.执行change1方法,将a1(实参)的引用赋值给a1(形参),在方法体中将a1(形参)引用地址所对应的堆中的A对象所对应的str重新赋值为changed,
* 退出方法后销毁a(形参)
* 3.打印a1(实参)引用地址所指向的堆内存中的A对象所包含的str对象,由于在change1方法中将str改为changed,故打印changed
*/
A a1 = new A("hello");
change1(a1);
System.out.println(a1.str);
}
private static void change(String str) {
str = "changed";
}
private static void change(A a) {
a = new A("changed");
}
private static void change1(A a1) {
a1.str = "changed";
}
}
class A {
public String str;
public A(String str) {
this.str = str;
}
}
该题是无意中看到的一道题目,尝后后发现于自己的判断相差很大,故翻阅相关资料了解后将自己的理解记录下来,如有错误请指正