public class Demo2_5 {
    public static void main(String[] args) {
        Integer a=new Integer(1);
        Integer b=new Integer(2);
        swap(a,b);
        System.out.println("a="+a+"  b="+b);
    }    public static void  swap(Integer a,Integer b){
        Integer temp=a;
        a=b;
        b=temp;
    }
}运行结果:a=1 b=2
Integer是封装类型,也就是对象,为什么在参数传递时任然时值传递而不是引用传递呢

解决方案 »

  1.   

    public class Demo2 {
    public static void main(String[] args) {
    Integer a = new Integer(1);
    change(a);
    //输出结果仍然是1
    System.out.println("a=" + a);
    } private static void change(Integer a) {
    a = new Integer(5);
    }
    }
    楼主的代码可以简化成上面这个,问题还是一样。
    Integer是引用数据类型,但是里面的value属性是final修饰的,意思是常量不可变。
    主方法把a的地址传给change方法,但是它拿到了a的地址却不能改变a指向的变量的值,只能把原来的地址改成指向“5”,当然对主方法里面的a没影响了。(注意,change方法里的a是局部变量,他和主方法里面的a不是同一个变量。
      

  2.   

    我补充下我楼上的回答,楼上说的有个地方不对:出现这个情况和value的值变不变是没关系的。
    我把楼主的swap方法的形参名字改了一下:
    public class Demo2_5 {
        public static void main(String[] args) {
            Integer a=new Integer(1);
            Integer b=new Integer(2);
            swap(a,b);
            System.out.println("a="+a+"  b="+b);
        }    public static void  swap(Integer aa,Integer bb){
            Integer temp=aa;
            aa=bb;
            bb=temp;
        }
    }
    以上的改动是对源程序没有任何影响的!!!
    你在下意识地把主方法的a和swap方法的a当作同一个对象。
      

  3.   


    我又看了一下源码,Integer中的value是私有的,而且也没有提供setter方法,所以对它的值是没有办法修改的,也就是没有方法使用a.value=123或者a.setter(123)去改变它的值,而且swap方法中的引用a只是main方法中主方法的复制,所以对于a=b之类的操作都只是改变了a的复制引用的值,而不是原本a,而Integer由于它的value是私有,而且没有setter方法,所以就没法改变Integer的值不知道这样理解是否正确
      

  4.   

    和其他对象一样,是引用传递没错,是你的swap程序写的有问题,本来引用传递就是传地址,你用局部变量不断改变地址,但却没有改变原地址指向对象的值。
    swap方法结束后,局部变量都变没,原来的地址的东西还没变。
      

  5.   


    谢谢解答
    这个代码是我在一篇文章上看到的,但是它抛出了一个问题“Integer是封装类型,也就是对象,为什么在参数传递时任然时值传递而不是引用传递呢”
    当时看到后感觉不知道怎么解释这个问题了
      

  6.   


    我又看了一下源码,Integer中的value是私有的,而且也没有提供setter方法,所以对它的值是没有办法修改的,也就是没有方法使用a.value=123或者a.setter(123)去改变它的值,而且swap方法中的引用a只是main方法中主方法的复制,所以对于a=b之类的操作都只是改变了a的复制引用的值,而不是原本a,而Integer由于它的value是私有,而且没有setter方法,所以就没法改变Integer的值不知道这样理解是否正确
    这样理解是没问题,但是这个程序里主要是因为你根本没有想去改指向对象的值,而是直接把main传给你的地址给替换掉,然后关起门来自己和自己玩,换来换去对原来mian方法中的参数没有任何的影响。
      

  7.   

    看 Integer 源码才会明白  Interger 有个 cache[] 缓冲 保存 128 数字。
      

  8.   

    严格来讲,java中没有真正的类似于指针的东西,swap方法中的形参a,b可以看做对主方法中a,b的引用拷贝,你直接对a,b操作是无效的,只有对操作对象中的元素时才会对原参数产生影响
      

  9.   

     2 楼 的对引用传递的理解有偏差,要是按照2楼的说法,输出结果是3,可结果是0
    public void change(int c[]) {
    c[2]=0;
    }
    @Test
    public void show() {
    int a[]= {1,2,3,4,5};
    change(a);
    System.out.println(a[2]);
    }
    引用传递传过去的是地址,c[2]修改之后,因为a数组也指向那个地址,所以说a[2]也会改变
    至于说interge是对象,不是基本类型,应该是引用传递。但是嘞,java机制中传参的时候,自动把interge拆箱为int,也就是基本类型,所以interge这样做的结果,和值传递一样。还有string类型也比较特殊,也不是基本数据类型,按说是引用传递,但它也是和值传递的结果一样。
      

  10.   

    在你调用swap方法时,在方法调用栈里,会从主内存中复制一份a,所以你对原来的引用a没有改变
      

  11.   


    怎样判断是否进行了拆箱呢,使用getClass()方法可以吗?比如a.getClass();如果输出为Integer就说明没有拆箱