Java是值传递还是引用传递(成神之路三)

官方的文档中标明:结论是值传递。

Java总是值传递的,但是sun称“一个对象的地址”为引用,当我们传递一个对象的值的时候,我们传递的是它的引用,这很容易迷惑初学者。

在此,问题的关键是“引用”这个词在表达“通过引用传递”时与我们通常在Java中的“引用”一词完全不同的意思。

在Java中引用通常意味着对一个对象的引用。但在编程语言理论中技术术语中,引用、值传递意味着一个存储着变量的存储单元的引用。

引用传递:

当一个参数传递给一个函数的时候,调用函数获得一个原始值的引用,而不是他的值的一个拷贝。如果这个函数修改了他的参数在调用代码中的值也会被改变,因为参数与参数都是用的相同的内存槽。很确定的Java只有一种传值方式(有助于保持事情的简单性)

对此,举个例子来体会一下:你不能用Java直接写一个交换函数去交换两个作为参数传递的值,不论他们是对象还是单纯的值。因为Java是值传递,包括指向一个方法的对象的指针。

Java是值传递的。我们所以为的按引用传递,其实传递的还是引用中地址的值(并且是它的一个拷贝),也可以理解为指针的值。让我们所疑惑的,只是“引用”这个词的含义,在Java中的引用和我们以为的引用是有所不同的。

对上述是不是懵懵懂懂,那具体可以看看下述文章。

首先,我们不要纠结值传递和引用传递的字面意义,容易陷入所谓的“一切传引用其实本质上是传值”这种无意义论战。

基本类型,值就直接保存在变量中。而引用类型,变量中保存的只是实际对象的地址。一般称这种变量为引用,引用指向实际对象,实际对象中保存着内容。参考下图:

preview

这里搞清楚赋值运算符(=)的作用

num = 20;

str = "java";

对于基本类型num,赋值运算符会直接改变变量的值,原来的值被覆盖掉。

对于引用类型str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变

如上图,"hello"字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)

调用方法时发生了什么?参数传递基本上就是赋值操作。

第一个例子:基本类型

void foo(int value){

 value = 100;

}

foo(num);//num没有被改变

第二个例子:没有提供改变自身方法的引用类型

void foo(String text){

 text = "windows";

}

foo(str);//str 也没有被改变

第三个例子:提供了改变自身方法的引用类型

StringBuilder sb = new StringBuilder("ipone");

void foo(StringBuilder builder){

 builder.append("4");

}

foo(sb);//sb被改变了,变成了"iphone4"。

第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。

StringBuilder sb = new StringBuilder("ipone");

void foo(StringBuilder builder){

 builder = new StringBuilder("ipad");

}

foo(sb);//sb没有被改变,还是iphone。

重点理解是第三四个

第三个例子:

preview

builder.append("4")之后

preview

第四个例子:

 

preview

builder = new StringBuilder("ipad");

preview

局部变量和方法参数在jvm中的存储方法是相同的,都是在栈上开辟空间来存储的,随着进入方法开辟,退出方法回收。以32位JVM为例,boolean,byte,short,char,int,float以及引用都是分配4字节空间,long,double分配8字节空间。对于每个方法来说,最多占用多少空间是一定的,这在编译时就可以计算好。

Java对对象采用的不是引用调用,实际上,对象引用进行的是值传递。

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

总结一下java中方法参数的使用情况:

  • 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
  • 一个方法可以改变一个对象参数的状态
  • 一个方法不能让对象参数引用一个新的对象

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值