文档章节

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

o
 onedotdot
发布于 2017/09/01 17:32
字数 991
阅读 6
收藏 0

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

先看一个例子

复制代码

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

想猜想的不一样!!!

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

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

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

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

赋值操作后

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

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

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

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

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

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

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

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

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

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

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

总结:

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

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

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

本文转载自:http://www.cnblogs.com/taixuyingcai/p/6373423.html

共有 人打赏支持
o
粉丝 6
博文 329
码字总数 14350
作品 0
朝阳
java中值传递的理解,C++中传值传递、引用传递和指针方式的理解

通过对参考文献中两篇文章的理解消化,自己运行测试分析总结如下: java的值传递理解: 代码1: public class Test { /** * @param args */ public static void main(String[] args) { Stri...

Nob
2014/09/20
0
1
java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java编程语言只有值传递参数。 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对...

黑泽明军
04/02
0
0
最最最常见的Java面试题总结-第一周

这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。 Github地址:https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试...

Amsour丶
08/08
0
0
java方法参数和C方法参数的区别

方法调用(call by) 是一个标准的计算机科学术语。方法调用根据参数传递的情况又分为值调用( call by reference ) 和引用调用( call by value ) 。江湖上有很多关于这两种调用的定义 ,最通常...

墙头草
2011/09/09
0
0
Java的方法传递参数的本质---值传递

JAVA中只有值传递,没有引用传递 任何数据(不管是基本类型,还是引用类型)传到一个方法里时,都是拷贝了一份,所以无法在一个方法里修改他们的值,当然,如果传递的是对象的话,也就是引用...

Zhao-Qian
2012/10/18
0
2

没有更多内容

加载失败,请刷新页面

加载更多

Oracle return exit continue

常在循环体中看到下面3种语句: return exit continue 举例说明 啥都没有 -- none begin for i in 1 .. 10 loop if i < 5 then dbms_output.put_line('i < 5, i = ' || to_char......

taadis
59分钟前
2
0
JSONObject 转换时出错 InvocationTargetException

JSONObject 转换时出错java.lang.reflect.InvocationTargetException 一时看不出来是什么问题。 挺奇怪的。 百度参考了一下这个 网页的解决方案 说是类型不对,空? 仔细查看代码,果然是有一...

之渊
今天
3
0
no such module 'pop'问题

在github上 clone 了一个 swift 项目,编译时提示"no such module 'POP'"错误,查了一下居然是因为podfile中指定的最低版本是iOS 11.0,大于我测试手机的iOS版本10.3.3,将Podfile中的最低版...

yoyoso
今天
3
0
redis 系列一 -- 简介及安装

1.简介 redis -- remote dictionary server 远程字典服务 使用 C 语言编写; 高性能的 key-value数据库; 内存数据库,支持数据持久化。 Redis 是一个开源(BSD许可)的,内存中的数据结构存...

imbiao
今天
4
0
nginx log记录请求响应时间

有时为了方便分析接口性能等,需要记录请求的时长,通过修改nginx的日志格式可以做到,如 添加一个新的log_format log_format timed_combined '$remote_addr - $remote_user [$time_local] "...

swingcoder
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部