gpt4 book ai didi

java - java中是否存在函数中的变量未链接的情况?

转载 作者:行者123 更新时间:2023-12-01 18:09:46 25 4
gpt4 key购买 nike

特别是,我想知道 arg 是否始终链接,或者只是链接,因为函数 decloration 是 static

在我编写数千行代码并期望它是一种方式之前知道它们是否有任何怪癖是很高兴的,但在一种边缘情况下它不是。

郑重声明,我了解 string = new String[2];里面changeValue()将创建一个新字符串,并且更改不会传播到 main string 的实例;

这里有一些示例代码来说明我所指的内容。

public class TestLink {

public static void changeValue(Object object) {
object.foo = "changed";
}

public static void changeValue(String[] string) {
string[0] = "changed";
}

public static void main(String[] args) {
String[] string = new String[2];
string[0] = "not changed";
changeValue(string);
if (string[0].equals("not changed")) {
System.out.println("not linked");
} else {
System.out.println("linked");
}
System.out.println(string[0]);
/*
output:
linked
changed
*/
}
}

最佳答案

从问题中的代码来看,听起来您真正要问的是:“是否存在一种边缘情况,我将数组引用传递到方法中并修改其内容,但这种修改并没有真的发生了吗?”

不,没有。让我们提取一些代码并更改一些名称,这样它们就不会产生误导:

public static void changeValue(String[] arg) {
arg[0] = "changed";
}

public static void main(String[] args) {
String[] foo = new String[2];
foo[0] = "not changed";
changeValue(foo);
if (foo[0].equals("not changed")) {
System.out.println("not linked");
} else {
System.out.println("linked");
}
System.out.println(foo[0]);
}

changeValue 接受数组引用(指向数组的值),并更改该数组的内容。如果代码编译(例如,所有类型等都是正确的)并且在运行时不会抛出异常(您没有将 null 或零长度数组传递给 changeValue),那么不,没有任何边缘情况是行不通的。

该代码发生了什么?

如果我们深入研究该代码中发生的情况,我们就会明白为什么答案是“否”。我发现图片可以提供帮助,所以让我们在此添加一些 ASCII 艺术。

这一行:

String[] foo = new String[2];

在内存中给我们这个:

                  +----------+foo(ref 5426)---->| String[] |                  +----------+                  | 0: null  |                  | 1: null  |                  +----------+

We have a variable, foo, that contains a value. The value is called an object reference because it refers to an object (in this case, an array, so we sometimes call it an array reference). That's just a value that tells the JVM where the object is. I'm showing it as ref 5426 just to show that it's a value like any other value, not something magical; I've picked 5426 completely at random, we never see the actual value, the JVM hides it from us.

Then you do this:

    foo[0] = "not changed";

给我们:

                  +-------------+foo(ref 5426)---->| String[]    |                  +-------------+     +---------------+                  | 0: ref 1897 |---->|    String     |                  | 1: null     |     +---------------+                  +-------------+     | "not changed" |                                      +---------------+

E.g., the first entry in the array contains value which is a reference to a string object.

Then we do this:

    changeValue(foo);

它从 foo 获取值并将该值传递给 changeValuechangeValue 接收参数 arg 中的值。所以现在我们有这个:

                  +-------------+foo(ref 5426)--+->| String[]    |               |  +-------------+     +---------------+               |  | 0: ref 1897 |---->|    String     |               |  | 1: null     |     +---------------+               |  +-------------+     | "not changed" |               |                      +---------------+arg(ref 5426)--+

Since main hasn't returned, foo still exists, and it has the value ref 5426. That value was copied into arg, so arg also has the value ref 5426. That value tells the JVM where the array is.

Then you do:

    arg[0] = "changed";

这给了我们:

                  +-------------+                       +---------------+foo(ref 5426)--+->| String[]    |                       |    String     |               |  +-------------+     +-----------+     +---------------+               |  | 0: ref 2785 |---->|  String   |     | "not changed" |               |  | 1: null     |     +-----------+     +---------------+               |  +-------------+     | "changed" |               |                      +-----------+arg(ref 5426)--+

数组中的第一个条目不再指向旧字符串,您已将该值替换为指向新字符串的新值。 (旧字符串会一直存在,直到垃圾收集器将其删除,但我们不再关心,我们没有任何对它的引用。)

changeValue 已完成,因此它返回,并且 arg (参数)消失。

由于 foo 仍然具有相同的值 (ref 5426),因此当您查找其中的第一个条目时,您会看到 放入其中的值>更改值

这如何告诉我们答案是“否”?

如果存在上述方法不起作用的极端情况,则必须发生以下情况之一:

  • foo 的值传递给 changeValue 并将其作为 arg 接收,由于某种原因不起作用。

  • foo 的值传递给 changeValue 并将其作为 arg 接收,制作副本由于某种原因数组。

  • 当我们使用它来获取数组并更改它时,我们得到的 ref 5426 存在一些差异。

不存在发生这些事情的任何边缘情况。 :-)

关于java - java中是否存在函数中的变量未链接的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33912013/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com