从一个Integer值的交换看引用传递和值传递

一个简单的栗子…

交换两个Integer的值,很简单哈?顺手一写

	public static void main(String[] args) {
        Integer a = new Integer(10086);
        Integer b = new Integer(10010);

        wrongChange(a, b);
        System.out.println("wrongChange_outer_a:" + a + ", b:" + b);
    }
    /**
     * wrong change
     * @param a
     * @param b
     */
    private static void wrongChange(Integer a, Integer b) {
        Integer temp = a;
        a = b;
        b = temp;
        System.out.println("wrongChange_inner_a:" + a + ", b:" + b);
    }

结果一出:

wrongChange_inner_a:10010, b:10086
wrongChange_outer_a:10086, b:10010

很显然嘛,是错误的…为啥嘛
是值传递和引用传递在作祟,为什么呢?
Java的数据类型分为基本数据类型和引用数据类型,在方法调用的时候,基本类型和引用数据类型的传值方式是不一样的。
对于基本数据类型来讲,方法调用时,是值传递,实参会复制一份基本数据类型的值传递给形参。而对于引用数据类型,实参会复制一份引用的地址传递给形参。

方法中的交换仅仅是形参对于值的引用替换,当方法调用结束后,虚拟机释放引用内存,并不会影响到方法外实参的引用地址,因此并不会交换a和b的值。

看下面的方法

	public static void main(String[] args) {
        Integer a = new Integer(10086);
        Integer b = new Integer(10010);

        rightChange(a, b);
        System.out.println("rightChange_outer_a:" + a + ", b:" + b);
    }
    /**
     * right change
     * @param a
     * @param b
     */
    private static void rightChange(Integer a, Integer b) {
        int temp = a.intValue();
        try {
            Field field = Integer.class.getDeclaredField("value");
            field.setAccessible(true);
            field.set(a, b);
            field.set(b, temp);
            System.out.println("rightChange_inner_a:" + a + ", b:" + b);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

结果:

rightChange_inner_a:10010, b:10086
rightChange_outer_a:10010, b:10086

结果虽然正确了,但其实还是有些问题,敬请期待后续文章…记得收藏点赞哦

你可能感兴趣的:(Java)