从学术严格角度来说JAVA中只有值传递!!!
可是就像JAVA编程规范那样约定俗成业界习惯了说成值传递和引用传递。
值传递: JAVA中基本数据类型是值传递
引用传递: JAVA中引用类型是引用传递面试
伟大的领导人说过,实践是检验真理的惟一标准。那么就从一道面试题开始吧。
首先建立一个实体Persion类(注意idea中安装Lombok插件)编程
import lombok.Data;
@Data
public class Persion {
int age;
String name;
int phone;
public Persion(String name) {
this.name = name;
}
}
复制代码
以后建立一个测试类bash
import com.demo.entity.Persion;
public class TestTransferValue {
public void changeValue1(int age){
age = 30;
}
public void changeValue2(Persion persion){
persion.setName("changeValue2");
}
public void changeValue3(String string){
string = "changeValue3";
}
public static void main(String[] args) {
TestTransferValue testTransferValue = new TestTransferValue();
int age = 20;
testTransferValue.changeValue1(30);
System.out.println("age:" + age);
Persion persion = new Persion("abc");
testTransferValue.changeValue2(persion);
System.out.println("persion name :" + persion.getName());
String str = "abc";
testTransferValue.changeValue3(str);
System.out.println("str:" + str);
}
}
复制代码
不卖关子直接上答案,从答案入手讲解值传递与引用传递的区别。jvm
首先程序的入口是main函数,在内存的栈区main方法属于栈低。
解析一: 声明基本数据类型age以后把age的值传递到changeValue1函数而且把值改变为30,此时涉及到变量做用域问题方法changeValue1中的变量age是30,可是main方法age在栈中指向的引用仍是20的,因此第一个打印是age=20;基本数据类型都是值传递;ide
解析二: 接下来来到了persion变量。声明persion变量等号的左边叫作引用,右边new的对象存放在内存堆中,准确的说是存放在堆中新生代的伊甸园区,顺便扩展一下 新生代:养老代= 1:2,新生代中分为伊甸园区:幸存区0:幸存区1 = 8:1:1。 此篇文章不作更多jvm扩展,有须要了解的关注做者后续会更新JVM相关知识。persion传递到changeValue2中将值改变为value2此时栈中persion指向堆中的地址值改变为changeValue2;继而打印结果为persion name :changeValue2,解释说明了引用传递。函数
重点来了 第三个按照上述的persion理解引用传递应该打印的是changeValue3,但是为何结果不对呢?听我娓娓道来: 铺垫知识,JAVA在建立String对象的时候会从字符串常量池中查找是否有和新建字符串相同的常量,若是有则返回此时两个对象的地址也就是hashcode是同样的,不然新建一个地址保存字符串;当字符串abc传递到changeValue3函数以后,查找发现池中并无changeValue3字符串,此时须要新建一个地址changeValue3函数中的string变量有了新的地址;可是此改变并无改变面函数中的str 地址因此打印的事str:abc。测试
以上就是值传递和引用传递的介绍,源码已经提供能够自行使用System.identityHashCode函数查看变量的内存地址。 若有错误欢迎留言指正,感谢您的阅读!!!ui