结论: java只有值传递
首先看代码把:
代码块
代码块语法遵循标准markdown代码,例如:
public class Test {
public static void main(String[] args) {
//基本数据类型
int a=7;
//引用类型。String 特殊对象
String b="皇马";
//引用类型。普通对象
TestEntity t=new TestEntity();
t.setName("c罗");
setValue(a,b,t);
System.out.println(a);
System.out.println(b);
System.out.println(t.getName());
}
public static void setValue(int a, String b, TestEntity t){
a=10;
b="巴萨";
t.setName("梅西");
}
}
class TestEntity{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1、说一下基本类型的情况
基本数据类型的创建是在栈上分配空间
int a=7;
如下图
setValue函数参数接到的是a值的副本。
如下图
因为java是值传递,函数内的a改变不会影响到外边的。
2、说一下引用类型中的String
java中的字符串比较特殊,一般的对象的引用变量都在函数的栈内存中分配,值存在堆中,比如new(“阿森纳”);就是在堆上创建一个对象。而 b=”皇马” 赋值这种只会在栈上创建引用变量,然后在常量池分配值。
如下图
setValue函数参数接到的是b值的副本。
如下图
注意!函数里的b被重新赋值。
如下图
字符在常量池上创建时,先检查有没有存在,如果有存在的直接引用,如果发现没有,新建一个。所以函数里的改变不会改变外部值。
3、说一下引用类型。普通对象
为什么在函数内设置对象的值,外部也会变呢?这不就是引用传递吗,我之前也是这么想的,后来看了许多博文发现不对。
TestEntity t=new TestEntity();
t.setName(“c罗”);
看图把:
setValue函数中参数接到一个对象引用的副本,如下图
新的对象,栈中的所有信息都一样,但是堆中的实例对象只有一个,是不会有副本。这就是与String不同的地方。由于两个变量的引用都相同,setValue中的对象设置新值,所以外部也会改变。如下图
这为什么叫做值传递呢?我个人感觉可能是因为栈中的对象重新赋值一份,这是两个独立的对象,只不过引用同一个堆中的实例对象,栈中的引用到最后也就是所谓的值。