java 为什么数组在方法调用中会改变?[duplicate]

ztyzrc3y  于 2023-01-24  发布在  Java
关注(0)|答案(6)|浏览(145)
    • 此问题在此处已有答案**:

Are arrays passed by value or passed by reference in Java? [duplicate](7个答案)
(93个答案)
3天前关闭。
当我这样写的时候:

public class test {

    void mainx()
    {
        int fyeah[] = {2, 3, 4};
        smth(fyeah);
        System.out.println("x"+fyeah[0]);
    }

    void smth(int[] fyeah)
    {
        fyeah[0] = 22;
    }
}

它打印x22;
当我这样写的时候:

public class test {

    void mainx()
    {
        int fyeah = 5;
        smth(fyeah);
        System.out.println("x"+fyeah);
    }

    void smth(int fyeah)
    {
        fyeah = 22;
    }
}

它不打印x22,而是打印x5。
为什么在第二个版本的函数中,值没有改变?它只改变了数组元素的值吗?

zfycwa2u

zfycwa2u1#

第一个示例中的fyeah变量包含对数组的引用(不是数组),而第二个示例中的fyeah整数包含整数
由于Java按值传递所有内容,因此将发生以下情况:

**在数组情况下:**将发送 * 数组引用 * 的副本,并更改原始数组。
**在int情况下:**将更改 * 整数 * 的副本,而原始整数不会更改。

lokaqttq

lokaqttq2#

这是因为你的int是一个原语,而smth方法创建了一个本地副本,这就是为什么它不能按照你想要的方式打印。对象也是通过值传递的,但是一个值传递给内存中的指针。所以当它被改变时,指针在两个方法中都保持不变,你可以看到改变。Read More Here

dgtucam1

dgtucam13#

好的,int在java中(实际上是所有有严格数据类型的语言)是一种原始数据类型,它只是该数据类型的一个变量,在java中这意味着它是通过值传递给方法的,所以当你传入参数时,会创建一个所传递变量的副本,方法中发生的任何操作都作用于该副本,而不是所传递的变量。
实际上,在java中,所有的东西都是通过值传递的,但是深入到我接下来要说的细节中似乎是不可取的。
对于数组,它是一个原始数据类型int的变量集合,所以数组的整个副本实际上并不是,对存储数组的内存的引用的副本,所以数组中int的值是从方法中的操作中改变的。
简而言之,方法不改变原语的外部值(int、float、double、long、char)与方法中的操作,如果你想得到这些操作的结果值,你必须把它返回给调用者。2操作确实改变了大多数对象和基元数组的值。3希望这能有所帮助。4真的不确定要得到多低的级别。也许别人可以清楚地解释为什么它的价值。我“得到”它,但发现很难帮助其他人理解。

e5nszbig

e5nszbig4#

从记忆力的Angular 来看:我们来分析一下你的第一个程序-
mainx中,fyeahint的数组,因此它是一个引用(或者一个指针,如果我可以的话)。这个引用指向堆内存中存储int数组的位置。假设地址为100。从这里开始连续的位置是三个int(假设从地址100、104和108开始分别是2、3和4)。
现在调用方法smth并传递引用。在方法中,还有另一个引用(属于int数组类型)。此fyeahmainx方法中的fyeah引用截然不同。现在,当您调用smth并从mainx传递fyeah时,smth方法中的fyeah被初始化为指向相同的位置(即内存地址100)当您访问fyeah的0元素并将其赋值为22时,它会到达内存位置100并将值22写入其中。当您返回到mainx方法时,fyeah引用仍然引用内存地址100。但该位置的值现在为22。因此,当您访问mainxfyeah的第一个元素时,将获得该值。
现在是第二个程序。mainx方法声明了一个int(不是数组,而是一个简单的int)并将其设置为5。此fyeah变量是在堆栈上创建的,而不是在堆上。值5存储在堆栈上。现在调用smth并传递此变量。在方法smth中,再次声明int变量,按名称fyeah(作为一个形式方法参数)。同样,这与mainx方法的fyeah不同,并且此fyeah也是在堆栈上创建的。此变量将被初始化为值5,从你作为参数传递给smthfyeah复制过来的。注意fyeah变量有两个不同的副本,都在堆栈上,两个都赋值为5。现在您将smth中的fyeah赋值为22。这不会影响mainx方法的fyeah,因此,当您返回到mainx并访问fyeah时,您会看到5。

ipakzgxi

ipakzgxi5#

int是一个值类型,所以5被直接传递给smthsmth只能修改本地副本。另一方面,数组是一个引用类型,所以数组的元素可以被修改。

kcrjzv8t

kcrjzv8t6#

从技术Angular 看,我会说

fyeah[0] = 22;

正在更改fyeah(指向的对象)的内容,而

fyeah = 22;

正在改变(变量)fyeah本身。
另一个例子:

void smth(Person person) {
    person.setAge(22);
}

正在更改该人(的内容),而

void smth(Person person) {
    person = otherPerson;
}

正在更改变量person-Person的原始示例仍然不变(并且,由于Java是按值传递的,因此此方法不会更改调用代码中的变量)

相关问题