函数不会改变java中的变量值?

function won't change value of variable in java?

我知道Java中的所有东西都是通过值传递的,但是下面的代码不应该打印2而不是1。

我所做的就是通过Integer并改变它的值。为什么打印1而不是2?

1
2
3
4
5
6
7
8
9
10
11
public static Integer x;

public static void doChange(Integer x) {
    x = 2;
}

public static void main(String arg[]) {
    x = 1;
    doChange(x);
    System.out.println(x);
}


非常感谢你的回答。我想我现在知道引擎盖下面发生了什么。我认为我看不到主函数的变化的原因是整数是不可变的,当我给它赋值时,它会创建新的对象并赋值给引用x;

如果我们能用可变数据重复同样的例子,我们会看到不同的输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static StringBuilder x;

public static void doChange(StringBuilder x)

{

    x.append("world");

}

public static void main(String arg[]) {
    x = new StringBuilder("hello");

    doChange(x);

    System.out.println(x);
}

输出:Hello World


装箱的int仍然不变,doChange中的x是指参数,而不是字段。为了显示正在发生的事情,这里是显式装箱的代码版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static Integer x;

// parameter 'x' is hiding field 'x'
public static void doChange(Integer x)
{
    // Update parameter 'x', not field 'x', to point to
    // new Integer object with value 2.
    // Since 'x' is by-value, caller will not see change
    x = Integer.valueOf(2);
}

public static void main(String arg[]) {
    x = Integer.valueOf(1);
    doChange(x);
    System.out.println(x);
}


您更改了参数,而不是类变量。重命名参数,它将起作用:

1
2
3
4
public static void doChange(Integer unused)
{
    x = 2;
}

原因是通过赋值(=)更改了实例。您的参数x被分配给了一个新实例(而不是您通过方法调用给它的实例)。解决方案是调用实例方法来更改实例的状态。但是:标量的对象类与其他类不同。整数实例是唯一的(不可变),不能更改整数实例的状态。

但是,如果您尝试使用自己的类(如mynumber)并使用实例方法调用(而不是assignment=),它将按预期工作:

1
2
3
4
5
6
7
8
9
10
11
12
public class MyNumber {
    private int number = 0;
    public set(int v) {
        number = v;
    }
    public get() {
        return number;
    }
    public String toString() {
        return Integer.toString(number);
    }
}

如果使用mynumber而不是integer,请将方法dochange更改为:

1
2
3
4
public static void doChange(MyNumber x)
{
    x.set(2);
}

当然,把声明改为:

1
public static MyNumber x;

…第一个任务主要是:

1
x.set(1);

希望这有助于理解。


这就是您在代码中解决问题的方法。我编了一个班级,叫La。注意doChange()方法中的La.x = 2;语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class La {

    public static Integer x;

    public static void doChange(Integer x) {
        La.x = 2;
    }

    public static void main(String arg[]) {
        x = 1;
        doChange(x);
        System.out.println(x);
    }
}

您正在将一个整数对象传递给dochange函数。在doOxEnter()中,您正在分配一个新的值,Java是自动装箱,即创建一个值为2的新整数对象并使参数指向它。

指向对象的变量基本上是指向内存地址的指针:请参阅以下答案:https://stackoverflow.com/a/1750197/2698109和https://stackoverflow.com/a/1750141/2698109

1
2
3
4
5
6
7
 public static Integer x; // an primitive Object

 // passing an object
 public static void doChange(Integer x) {
    // under the hood Java is doing this
    x = new Integer(2);
 }

将方法签名更改为

1
public static void doChange(int x) {

它应该像预期的那样工作。


你自己回答了问题:)。

由于通过值传递,dochange()方法将具有值的副本。所以无论它在该方法中做什么,它都不会影响在主方法中声明的实际"x"变量。