为什么我的wrap int不保留此方法所做的更改?

时间:2012-06-04 10:45:42

标签: java pass-by-reference

private static String getArgValue(String[] argsString, int[] jIndex, String classTag) {

    String thisToken;

    for( ; jIndex[0]<argsString.length ; jIndex[0]++) {
        System.out.println("jIndex[0]: " + jIndex[0]);

        if (condition) {
            // yadda yadda yadda
            jIndex[0]++;
            System.out.println("jIndex[0]: " + jIndex[0]);
            return retString;
        }
    }

    return retString;
}

我尝试用Integer和数组包装它,但都没有对原始i变量进行更改。怎么称呼:

int[] j = new int[1];

for(int i=2; i< argsString.length; i++) {
    // yadda yadda yadda
    System.out.println("opening i: " + i);
    j[0] = i;

    thisArgValueString = getArgValue(argsString, j, thisArgClassString);
    System.out.println("closing i: " + i);
}

示例输出:

opening i: 2
jIndex[0]: 2
jIndex[0]: 3
jIndex[0]: 5
closing i: 2

5 个答案:

答案 0 :(得分:2)

尝试打印你的int holder而不是我自己:

System.out.println("closing i: " + j[0]);

或者你可以简单地重新分配i:

i = j[0];
System.out.println("closing i: " + i);

您的原始变体i不会自行更改,因为它是原始类型。整数也没用,因为它是不可变的。所以你提供的代码本质上是正确的方法。您只需要理解,j[0] = i仅将i的值分配给j[0],并且不会将j[0]的内容与i相关联。因此,您可以从那时开始使用j[0](就像这篇文章中的第一个代码一样)或者从i重新分配j[0](就像这篇文章中的第二个代码一样)。

答案 1 :(得分:1)

Integer是不可变的,但您显然试图使用它,就好像它是可变的一样。那不行。

另一方面,int[1]可以用作可变的int持有者......

...以及似乎在您的示例中工作的原因是,在上一个打印语句中,您正在打印i而不是j持有者您在getArgValue电话中更新了。将最后一个语句更改为:

    System.out.println("closing i: " + j[0]);

请记住,这是模拟按引用调用,而不是真正的逐个引用。你必须按正确的顺序跳过箍,才能使模拟工作。

答案 2 :(得分:1)

Java是按值传递的,并且您期望的行为(即i的内容更改)与对象一致,其中您传递的值是对象引用。但是,对于诸如字符,整数和双精度之类的基元,您将传递实际数据本身。你输入j [0]的不是变量i,而是i的内容。因此,现在有两个具有相同内容的存储器位置 - j [0]和i。但是,当您更改j [0]时,i不受影响,因为它完全不相关 - 您只需将j [0]的内容复制到i中。将对象传递给方法时,实际上是在传入对象引用,因此您指的是同一个对象。通过将i转换为Integer,您将自动进行自动装箱,也就是说,您正在制作i的副本,然后使用对象Integer将其包装,然后销毁该对象。

答案 3 :(得分:1)

您的代码段显示您对数组可变性和通过引用传递的误解存在误解。

让我给你一个更简化的例子,它将删除围绕问题核心的所有非必要的废话。

public static void main(String[] args) {
   int numberToModify = 42;
   int [] arr = new int[1];
   arr = numberToModify;
   System.println("numberToModify="+numberToModify );
   System.println("arr[0]="+arr[0]);
   doStuff(arr);
   System.println("numberToModify="+numberToModify );
   System.println("arr[0]"+arr[0]);
}

private static void doStuff(int[] array){
   array[0] = 100;  
}

你应该看到的是打印出来的

numberToModify=42
arr[0]=42
numberToModify=42
arr[0]=100

在您的代码示例中,您似乎期望在方法内部修改数组时,变量i(此处为numberToModify)也应该更改。它没有,因为数组包含实际的值类型(因为int s是主要的,并且灵长类通过值传递)。

答案 4 :(得分:0)

所以你想让变量i保留对它做的所有改变吗?您是否尝试将其声明为Integer对象? int是一个基本类型,所以你不能通过引用传递它,将它包装在任何东西中只会分配它的值。尝试做这样的事情:

for(Integer i=2; i< argsString.length; i++) {
// yadda yadda yadda
System.out.println("opening i: " + i);
j[0] = i;

thisArgValueString = getArgValue(argsString, j, thisArgClassString);
System.out.println("closing i: " + i);

}

并查看是否能解决您的问题。

希望有所帮助。