IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    理解JAVA的传值方式

    阿里黑伯发表于 2015-08-10 11:34:23
    love 0

    作者:黑伯

    问题: Java的参数传递的是值还是引用?

    我们经常会被问到这样的问题,当我调用某个方法时,通过参数传递过去的是变量本身,还是一个变量的复制品?问题的答案留到讨论后给出。


    首先,你需要了解下java变量的分类:java中的变量分为

    1. 基本类型
    2. 接口类型
    3. 类类型
    4. 数组类型

    其中后面三种统称为引用类型,而基本类型分为三种,

    1. 数字类型
    2. boolean
    3. returnAddress

    数字类型又分为

    1. 浮点类型
    2. 整数类型
    3. 浮点

    整数又有具体的内容,这里不再展开说明。其中,returnAddress是java虚拟机内部使用的类型,它被用来实现java程序中finally子句。这里主要看引用类型和基本类型数字类型情况(boolean类型的情况和基本类型一致).

    先看参数为基本类型的情况:

    public class Demo1 {
        public void swap(int a, int b) {
            a = a ^ b;
            b = a ^ b;
            a = a ^ b;
            System.out.println("swap: a=" + a + ",b=" + b);
        }
    
        public static void main(String[] args) {
            Demo1 demo1 = new Demo1();
            int a = 1;
            int b = 2;
            demo1.swap(a, b);
            System.out.println("main: a=" + a + ",b=" + b);
        }
    }
    

    输出

    swap: a=2,b=1
    main: a=1,b=2
    

    上面的代码想通过swap交互a和b的值,在swap内部,变量a和b已经交换成功了,但在main中a和b的值依然是原来的值.

    再看参数为引用的情况:

    </pre>
    <pre>public class Demo2 {
         public void swap(StringBuffer a,StringBuffer b){
                StringBuffer c = a;
                a=b;
                b=c;
             System.out.println("swap: a="+a+",b="+b);
         }
    
       public static void main(String[] args) {
          StringBuffer a = new StringBuffer("a");
          StringBuffer b = new StringBuffer("b");
          Demo2 demo2 = new Demo2();
          demo2.swap(a, b);
          System.out.println("main: a="+a+",b="+b);
       }
    }</pre>
    <pre>

    大家可以先思考下,上面的输出是什么?

    输出:
    swap: a=b,b=a
    main: a=a,b=b

    和参数为基本类型的情况结果是一致的.
    为什么会出现这种情况呢?

    我们来分析下上面的参数传递过程,以Demo2为例:

    图1是swap未计算前的参数值,

    图2是swap计算后的参数值.

    从图中可以看出,swap的计算过程只能改变swap内部变量a和b的值,不能改变main中的a和b变量的引用值,换言之,参数的传递只能传值,不存在传引用一说.

    请注意,上面我说不能改变a和b变量的引用值,可没说不能改变a和b指向的对象的值.再看下面的例子:

    </pre>
    public class Demo3 {
     public void swap(StringBuffer a,StringBuffer b){
     a.append(b);
     StringBuffer c = a;
     a=b;
     b=c;
     System.out.println("swap: a="+a+",b="+b);
     }
     public static void main(String[] args) {
     StringBuffer a = new StringBuffer("a");
     StringBuffer b = new StringBuffer("b");
     Demo3 demo3 = new Demo3();
     demo3.swap(a, b);
     System.out.println("swap: a="+a+",b="+b);
     }
    }
    这个会输出什么呢?
    
    swap: a=b,b=ab
    swap: a=ab,b=b
    
    

    这个就是上面所说的,在swap内部的计算过程中,改变了main.a所指向对象的值.

    就像下面的图所描述的那样:

    、

    但根本上,swap不能改变main中a和b的引用值.

    另外贴一句sun公司官方文档上的描述这一问题的原话:

    Java is always pass-by-value.when object is passed as a argument, be careful with that it is also the copy of reference

    所以,现在你应该知道,java传递的只会是值,没有传递引用.

    原创文章,转载请注明: 转载自并发编程网 – ifeve.com

    本文链接地址: 理解JAVA的传值方式



沪ICP备19023445号-2号
友情链接