• Java到底是按值传递还是按引用传递?


    今天刷牛客网的题,其中一题是这样的

     1 public class Test1 {
     2 
     3     public static void main(String[] args) {
     4         Test1 t1 = new Test1();
     5         t1.first();
     6     }
     7     
     8     public void first(){
     9         int i = 5;
    10         Value v = new Value();
    11         v.i = 25;
    12         second(v, i);
    13         System.out.println(v.i + " " + i);
    14     }
    15     
    16     public void second(Value v, int i){
    17         i = 0;
    18         v.i = 20;
    19         Value val = new Value();
    20         v = val;
    21         System.out.println(v.i + " " + i);
    22     }
    23 }
    24 
    25 class Value {
    26     public int i = 15;
    27 }

    最终输出是:15  0  20

    我以为的输出是:15  0  15

    我的疑问在于第20行。


    从上面引发了一个问题,Java到底是按值传递还是按引用传递?

    以前,认为是值传递,是通过一个简单的swap例子

     1     public static void main(String[] args) {
     2         int a = 10;
     3         int b = 20;
     4         swap(a, b);
     5         System.out.println("此时a为: " + a);
     6         System.out.println("此时b为: " + b);
     7     }
     8 
     9     public static void swap(int x, int y){
    10         int temp = x;
    11         x = y;
    12         y = temp;
    13         System.out.println("此时x为: " + x);
    14         System.out.println("此时y为: " + y);
    15         System.out.println();
    16     }

    结果为:

    此时x为: 20
    此时y为: 10
    
    此时a为: 10
    此时b为: 20

    如果是按引用传递,那么结果就不会这样。

    可是,牛客网上的那道题又把我绕进去了。翻了翻该题的评论,大部分都说是值传递,但是仍然有人说提出引用传递的疑问。

    不得已,翻书,Java核心技术卷1 第十版  page118~121

    还有,搜索相关话题


    结论:Java按值传递

    总结:

      方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。

    解释:

        无论方法的形参中放的是基本类型参数,还是引用类型参数,方法得到的永远只是一个拷贝或者副本。

        所以,上面的swap例子中,swap方法的形参  x、y  只是一个原始参数的副本,但是他们的值都是一样的。

        此时,我在swap方法里改变了  x、y 的值,也只是改变了副本的值,对原始值没有任何影响

        而对于引用参数的传递,传递的仍然是引用参数的副本,只不过这个副本里放的是参数的地址,也就是说,他们此时指向了同一个地址

        如果此时副本改变了此地址中的值,那么相应的引用参数所存的值也会被改变

        可是,为什么牛客网试题,第20行执行后,v 已经指向了 val,而 val 中 i 的值为15,最终first方法中输出的却是20呢?

        因为 -- 当第20行还未执行时,v.i = 20, 此时 i 的值变为20,first方法中的 v 和 second 中形参的 v 还是指向同一地址的,

        但是第20行执行过后,second 中的 v 已经指向 了一个新的地址,也就是 val 指向的地址,

        那么, 这时候 second 中的 v 已经和 first 中的 v 断掉了联系,两者已经属于你走东,我走西,各无瓜葛的状态

        所以,在后面 second 中的 v 你怎么样变,都影响不了原本的引用参数。

        小结这段话:作为引用参数副本,只要后期不重新指向一个新的地址,那么副本改变指向地址中的值,引用参数中的值也会被改变


    相关链接:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html

    相关阅读:Java核心技术 卷1 第十版  Page118~121

         

  • 相关阅读:
    C#时间格式转换问题(12小时制和24小时制)
    ajax跨域请求webservice webconfig配置
    C#时间戳转化为DateTime
    C#生成缩略图
    codeforces-1348-C Phoenix and Distribution
    P4314 CPU监控
    YangK's dfs序与树链剖分
    Yangk's 静态主席树
    P2253 好一个一中腰鼓!
    codeforces-1341D-Nastya and Scoreboard 记忆化搜索
  • 原文地址:https://www.cnblogs.com/shadowdoor/p/9135555.html
Copyright © 2020-2023  润新知