java中函数是值传递还是引用传递?

摘要:
有两种转移:价值转移和参考转移。还有两种转移:只有价值转移。在这里,我只想提出个人意见。让我们举一个例子,publicclassTest1{publicstatic void main{inta=10;changeNum;System.out.println;}staticvoidchangeNum{a=100;System.out.pintln;}}结果:changeNuma=100maina=10意味着基本值类型实际上传输了值的副本。传递函数后,它与原始值无关。在函数中更改此数字的值不会影响原始值。这让我们感到奇怪,为什么函数没有更改引用点指向的对象?

相信有些同学跟我一样,曾经对这个问题很疑惑。在网上也看了一些别人说的观点,评论不一。有说有值传递和引用传递两种,也有说只有值传递的,这里只说下个人见解

先看一个例子

public class Test1 {

    public static void main(String[] args) {
        int a = 10;
        changeNum(a);
        System.out.println("main a=" + a);
    }
    
    static void changeNum(int a) {
        a = 100;
        System.out.println("changeNum a=" + a);
    }
}

结果:

changeNum a=100
main a=10

说明对于基本的数值类型其实传递的是一份数值的拷贝,传入函数之后跟原来的值就没有关系了,在函数中改变这个数的值也不会影响到原来的值。

再看一个例子

public class P {
    String name = "P";
    public P(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return name;
    }
}

public class Test {
    static P p1 = new P("p1");
    public static void main(String[] args) {
        P p = new P("P");
     System.out.println("before change p:" + p.toString); changeObj(p); System.out.println("after change p:" + p.toString()); }
static void changeObj(P p) { p = new P("pp"); System.out.println("change p:" + p.toString()); //p = p1; //System.out.println(p.toString()); } }

这个例子中的运行结果会是什么呢?

在这个例子中传入的是一个对象类型的数据。

我们先来猜想一下:如果传入的是一个对象的引用,在函数中改变了这个引用所指向的对象,那么外部的引用"p"应该是指向了新创建的P("pp")的对象才对

所以猜想的结果是:

before change p:P
change p:pp
after change p:pp

那让我们来实际运行一下看看结果,实际的结果是:

before change p:P
change p:pp
after change p:P

想猜想的不一样!!!

这就让我们很疑惑了,为什么函数没有改变引用所指向对象呢?

其实是这样的,首先要理解“=”赋值操作的意义,

对于基本类型来说“=”赋值操作是直接改变内存地址上的值,

而对引用类型来说“=”赋值其实是改变引用变量所指向的内存地址。

java中函数是值传递还是引用传递?第1张

赋值操作后

java中函数是值传递还是引用传递?第2张

引用的赋值并没有对原来的对象造成影响,"hello"对象仍然是存在的,只是str又指向了新的"world"对象

理解了赋值操作后,现在来说下函数的参数传递

 函数的参数实际上就是函数内部的一个局部变量,从外部传值给这个参数实际上就是一个赋值的过程。

来看看第一个例子,传一个定义一个int类型名称为a的形式参数,其实完全可以把名称改为b

然后把外部变量a的值传递给函数的变量,就是赋值。基本类型的赋值就是把外部a变量的10赋值给函数变量a,所以这其实是两个变量,两者之间没有任何关系,

所以对函数内部变量的改变也不会对外部的变量造成影响。

再来说下引用类型的传递,其实是一个道理。

在传递的时候是把一个对象的内存地址赋值给函数内部的引用类型的局部变量

java中函数是值传递还是引用传递?第3张

如上图所示,两个变量是指向同一个对象的。

在第二个例子中,我们在函数内部新创建了一个对象,并重新赋值给内部变量p,其实是改变了内部变量的引用所指向的对象,如下图所示

java中函数是值传递还是引用传递?第4张

所以对外部的p变量是没有影响的。

总结:

函数参数传递其实是一个赋值的过程,基本类型传递的是数值,引用类型传递的引用对象的内存地址。

另外一点要特别注意,函数的参数其实是函数内部的局部变量。不要跟外部变量混淆

以上内容均为原创,转载请注明出外 http://www.cnblogs.com/taixuyingcai/p/6373423.html

免责声明:文章转载自《java中函数是值传递还是引用传递?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇更新!ArcMap和ArcGIS Pro加载百度影像地图ArcGIS中的三种查询下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

echarts使用技巧(一)echarts的图表自适应resize问题、单选、缩放等

因此,当浏览器发生调整大小事件时,让它触发rechart调整大小事件来重新绘制画布。使用窗口。resize=myChart resize;通过将窗口的调整大小事件分配给回声调整大小事件,可以实现自适应。当然,这是单一图表的情况。如果有多个图表,它将无法工作。...

grep多条件查找"与","或"

这里以jps命令为例jps查看全部的jvm进程"与"查找下图是所有jvm进程如果想查找256891ThriftServer服务用"与"查找可以理解为是条件查找命令:jps|grep-eer|grep-eT"或"查找方法一:grep-E'A|B'和grep-eA-eB方法二:egrep'A|B'方法三:awk'/A|B/'...

hiveserver2启动卡住问题解决方案

问题分析:hiveserver2可能是Hadoop集群进入安全模式,导致hiveserver2连接不上集群临时解决方案:离开安全模式即可#查看安全模式情况hdfsdfsadmin-safemodeget#离开安全模式hdfsdfsadmin-safemodeleave#进入安全模式hdfsdfsadmin-safemodeenter问题再分析:如何永久性的解...

如何给LINUX红帽子版本配置IP(转)

如果需要绑定另一个IP地址,只需在文件名中添加一个,并在文件中的DEVICE中添加eth0:x。LINUX可以支持多达255个IP别名,多个网卡绑定到一个IP地址,并且可以使用多个网卡创建具有相同IP地址的虚拟网卡。事实上,这种技术已经存在于Sun和Cisco中,它们分别被称为中继和以太网信道技术。在Linux中,这种技术被称为绑定。...

Nginx反向代理缓冲区优化

为了为不同域名的业务需求设置代理_ bufferingproxy_缓冲参数用于控制是否打开后端响应内容的缓冲区_缓冲区将缓冲到硬盘(缓冲区目录由_temp_path命令指定),...

pycharm最新版本激活码(永久有效) python安装教程

输入python以查看当前版本的python。您可以输入“print'helloworld”并单击下载以启动PyCharm://pan.baidu.com//1eVdm4dUPKn3ZY_Xj kqNXw提取代码:l83f2,下载破解补丁(版本2018.3.5)下载链接至地址:...