当它是像变量数组的值这样的参数时,如何更改Integer值?

cow*_*331 6 java integer pass-by-reference pass-by-value

public static void main(String[] args) {
    Integer i = new Integer(0);
    int[] arr = {1};
    p1(i);
    p2(arr);
    System.out.println(i);
    System.out.println(arr[0]);
}


public static void p1(Integer i) {
    i = 2;
}

public static void p2(int[] i) {
    i[0] = 2;
}
Run Code Online (Sandbox Code Playgroud)

//输出:0,2

我怎样才能更改i的值,就像我更改arr的值一样?

Jon*_*eet 15

你不能改变的变量值imain从内p1方法,因为该参数按值传递:参数ip1从完全独立的i变量,这只是他们在方法开始时相同的值.Java的始终使用传递值语义-但是当参数类型是一个类,它是一个基准是按值传递.

事实上,你不改变的价值arr,无论是-它像以前一样是相同的数组的引用,但该值数组已经改变.这就是你不能做的事情Integer,因为它Integer是一种不可变的类型.

如果你想要一个类似的可变类Integer,你可以使用AtomicInteger:

public static void main(String[] args) {
    AtomicInteger i = new AtomicInteger(0);
    modify(i);
    System.out.println(i);
}

private static void modify(AtomicInteger x) {
    x.set(2);
}
Run Code Online (Sandbox Code Playgroud)

但是我通常会这样做 - 我通常会尝试不修改方法参数所引用的对象.相反,我编写计算单个结果的方法,然后返回.

  • @walkeros:不,它确实*不是*通过引用传递,因为在Java中没有通过引用传递.请阅读http://javadude.com/articles/passbyvalue.htm或关于此主题的数百个问题.我已经解释过OP所要求的不能直接完成,所以我给出了类似*(但可变)类型的答案. (2认同)
  • @walkeros:不,它不会像通过引用那样传递 - 因为否则在方法*中改变`i`会*修改调用者的变量.(这就是传递引用的全部内容.)请注意,我没有说对象是按值传递的 - 我说*reference*是按值传递的.你是那个误导 - 而且不准确 - 在这里,我担心,声称Java使用pass-by-reference.将它与C#这样的语言进行比较,默认情况下**就像Java一样,但也允许使用`ref`修饰符进行传递. (2认同)

Dmi*_*urg 5

您可以使用AtomicInteger,它允许更改,而不是Integer

public static void main(String[] args) {
    AtomicInteger i = new AtomicInteger(0);
    p1(i);
    System.out.println(i);
}


public static void p1(AtomicInteger i) {
    i.set(2);
}
Run Code Online (Sandbox Code Playgroud)