Java考虑将List参数作为参考

时间:2014-06-04 07:52:12

标签: java pass-by-reference pass-by-value

我正在做一些RnD我遇到了这个差异

我的java代码如下

public class Main {    
public static void main(String[] args) {
    Integer x = 10;
    increment(x);
    System.out.println("print x" + x);

    List<String> strList = new ArrayList<String>();

    strList.add("one");
    strList.add("two");
    strList.add("three");
    strList.add("four");
    strList.add("five");
    strList.add("six");
    System.out.println("Before removing");
    for (String string : strList) {
        System.out.println("item " + string);
    }

    removeSomeItem(strList);
    System.out.println("After removing");
    for (String string : strList) {
        System.out.println("item " + string);
    }

}

private static void removeSomeItem(List<String> strList) {
    strList.remove(0);
    strList.remove(4);
}

private static void increment(Integer x) {
    x++;
    }
}

我出了上面的代码,如下所示

print x10
Before removing
item one
item two
item three
item four
item five
item six
After removing
item two
item three
item four
item five

我的问题是,当我发送Integer进行操作时,它的行为与我发送List<String>时的行为类似,其行为类似于参考,为什么会出现这种差异? 任何人都可以解释

3 个答案:

答案 0 :(得分:3)

主要区别在于Integer类是不可变的,因此您没有在main方法中看到更改。

x++; // this will simply return a new Integer

要查看差异,请尝试使用主要方法:

x = increment(x);

并在增量方法中,将其更改为:

return x++;

但是,使用列表示例,您只是将引用的副本传递给列表。只要该引用未设置为新对象(它不是'),它就能够更新您传递的原始列表。

答案 1 :(得分:0)

这正是发生的事情

private static Integer b;

public static void main(String[] args) {
    Integer x0 = 10;
    b = x0;
    increment(x0);
}

private static void increment(Integer x1) {
    //x1 == b is true
    x1++;  //implies x1 = x1 + 1;
    //x1 == b is now false
    //at the end of the day, you've done nothing to x0 or b
}

编辑:此代码将失败,因为显然,JVM正在缓存-128到127之间的整数值,see here,设置x0 = 150并测试。

public class Main {

    static Integer b;

    public static void main(String[] args) {
        Integer x = 150;
        b = x;
        increment(x);
    }

    private static void increment(Integer x) {
        System.out.println(x == b); //true
        x++;
        System.out.println(x == b);  //false
        b++;
        System.out.println(x == b);  //false
    }

}

答案 2 :(得分:0)

好的,

removeSomeItem(strList);

您正在将原始ArrayList的地址传递给方法,因此当使用该引用删除某个值时,原始ArrayList也会更改(实际上它们是具有两个访问点的单个对象,我的意思是引用)。

但是在Integer的情况下,您也传递引用,并且增量(Integer x)方法接收原始引用。但是当我做类似的事情时,整数是不可变的,

x++;

在后台,它的工作就像

x=new Integer(x+1);

这就是ArrayList更改时原始Integer保持不变的原因。