- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在理解下面的代码中发生了什么时遇到问题。数组 c
和 d
的行为是我所期望的。但是 a
和 b
是怎么回事? (我也用普通的标量变量尝试过这个,在任何一种情况下都没有发生令人惊讶的事情。)
输出被复制到 RH 注释中。
import java.util.Arrays;
public class ArraysParadox {
public static void main(String[] args) {
int[] c = {1, 2, 3};
int[] d = {6, 5, 4, 3};
System.out.print("c: ");
System.out.println(Arrays.toString(c)); // c: [1, 2, 3]
System.out.print("d: ");
System.out.println(Arrays.toString(d)); // d: [6, 5, 4, 3]
System.out.println("--- swap ---");
int[] tmp = c;
c = d;
d = tmp; // <----- Magic?
System.out.print("c' (=d): ");
System.out.println(Arrays.toString(c)); // c' (=d): [6, 5, 4, 3]
System.out.print("d' (=c): ");
System.out.println(Arrays.toString(d)); // d' (=c): [1, 2, 3]
System.out.println("--- c = 0 ---");
Arrays.fill(c, 0);
System.out.print("c (=0): ");
System.out.println(Arrays.toString(c)); // c (=0): [0, 0, 0, 0]
System.out.print("d (=c): ");
System.out.println(Arrays.toString(d)); // d (=c): [1, 2, 3]
System.out.println("--- d = 1 ---");
Arrays.fill(d, 1);
System.out.print("c (=d): ");
System.out.println(Arrays.toString(c)); // c (=d): [0, 0, 0, 0]
System.out.print("d (=1): ");
System.out.println(Arrays.toString(d)); // d (=1): [1, 1, 1]
System.out.println("================");
int[] a = {1, 2, 3};
int[] b = {6, 5, 4, 3};
System.out.print("a: ");
System.out.println(Arrays.toString(a)); // a: [1, 2, 3]
System.out.print("b: ");
System.out.println(Arrays.toString(b)); // b: [6, 5, 4, 3]
a = b;
System.out.print("a (=b): ");
System.out.println(Arrays.toString(a)); // a (=b): [6, 5, 4, 3]
System.out.println("--- α = 0 ---");
Arrays.fill(a, 0);
System.out.print("a (=0): ");
System.out.println(Arrays.toString(a)); // a (=0): [0, 0, 0, 0]
System.out.print("b (=a?): ");
System.out.println(Arrays.toString(b)); // b (=a?): [0, 0, 0, 0] ???
System.out.println("--- b = 1 ---");
Arrays.fill(b, 1);
System.out.print("b (=1): ");
System.out.println(Arrays.toString(b)); // b (=1): [1, 1, 1, 1]
System.out.print("a (=b?): ");
System.out.println(Arrays.toString(a)); // a (=b?): [1, 1, 1, 1]
}
}
根据这篇文章,c
和 d
的可交换性表示按值传递:Java is Pass-by-Value, Dammit! . (我也看了java array pass by reference does not work?,但是看不懂提问者的英文,而且方法调用模糊了例子。)
请注意,注释掉 d = tmp;
行后,c
和 d
表现出与 a< 相同的奇怪行为
和 b
。我仍然不知道该怎么做。
谁能解释一下 a
和 b
的行为如何用值传递来解释?
事实证明,我帖子中的主要问题不是按值传递,而是别名。为了弄清楚按值传递和指针之间的区别,我将以下方法添加到我的代码中并用它来(尝试)交换 c
和 d
(由上面链接的 JavaDude 文章链接的 article 建议。
static <T> void swap (T c, T d) {
T tmp = c;
c = d;
d = tmp;
}
结果是 c
和 d
没有改变。如果 Java(如 C)将指向 c
和 d
的指针传递给该方法,这将是可行的,但它只是传递它们的值,而原始变量保持不变。
将 a = b
更改为 a = b.clone();
或 a = Arrays.copyOf(b, b.length);
给出了我期望的行为。此代码也有效:
int[] tmp = new int[b.length];
System.arraycopy( b, 0, tmp, 0, b.length );
a = tmp;
描述的相对时间here .
最佳答案
这里没有任何“奇怪”的事情发生:数组变量是对实际数组(在其他语言中也称为指针)的引用。当您操作数组变量时,您所做的就是操作指针。
当您将一个数组变量分配给另一个数组变量时,您会为您分配的变量所指向的数组创建一个别名,并使之前被分配的变量所指向的数组符合垃圾处理条件 Collection 。因为赋值 a = b
使 a
成为 b
的别名,所以用数据填充 b
的行为与用数据填充 a
:一旦赋值完成,a
和 b
只是同一事物的两个不同名称。
就按值传递而言,您的示例中没有发生任何事情:按值传递的概念仅适用于将对象作为参数传递给您调用的方法时。在您的示例中,变量 a
、b
、c
和 d
不是方法参数,它们是局部变量.您确实通过对方法 toString
和 fill
的引用来传递它们(或者更准确地说,您通过值将对对象的引用传递给 toString
和 fill
,因为在 Java 中一切都是按值传递),这就是为什么通过 fill
对数组所做的修改在方法返回时可见。
关于java - 等式 Java 数组中的奇怪之处 : References vs. 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10923949/
我想在 java 中声明一个对象,就像在 C++ 中指向指针的指针,让我给你看一个例子: //*** At the application startup //Initialize a setting
考虑这段代码, struct A {}; struct B { B(const A&) {} }; void f(B) { cout << "f()"<
我正在尝试将一个C程序翻译成Rust。。C程序具有以下结构(归结为MRE):。在一个函数中,我将执行以下指针魔术:。不,我的问题是:我将如何在铁锈中实现同样的目标?。到目前为止,我在《铁锈》中尝试过的
我目前正在尝试将一个C程序翻译成Rust。。C程序具有以下结构(归结为MRE):。在一个函数中,我将执行以下指针魔术:。不,我的问题是:我将如何在铁锈中实现同样的目标?。到目前为止,我在《铁锈》中尝试
这个问题在这里已经有了答案: Add managed DLL dependencied to unmanaged C++ project (1 个回答) 关闭 6 年前。 我有这样一个场景: 使用
这是一个常见问答的集合,这也是一个社区维基,所以每个人都被邀请参与维护它。。正则表达式正在遭受给我ZE代码类型的问题和没有解释的糟糕答案。此参考旨在提供指向质量问答的链接。。此参考适用于以下语言:PH
我正在尝试在方案中模拟堆栈。我正在使用 DrScheme 并选择语言 R5RS。我需要创建 pop、push 和 peek 的函数。但我无法弄清楚如何通过引用传递。我已经阅读了一些关于盒子的信息,但是
我陷入了这个错误。我将代码部署在生产服务器上,它在端口 80 上运行。当我尝试登录管理页面时。如图所示,它给了我 403 错误。 可能是什么原因?我的 Django 代码或 nginx 配置有问题吗?
这是一段简单的 C++ 代码: A foo(){ A a; // create a local A object return a; } void bar(const A & a_r){ }
我正在使用从 torrenteditor 获取的 php 脚本来创建 torrent 文件,但是当我使用指定的方法创建新的 torrent 文件时,torrent 文件被创建但我收到很多通知。,就像这
MySQL: REFERENCES vs FOREIGN KEY + REFERENCES 我认为 REFERENCES 是更冗长的 FOREIGN KEY REFERENCES 语法的某种速记语法。
我想使用基于另一个方法引用的方法引用。这有点难以解释,所以我给你举个例子: Person.java public class Person{ Person sibling; int a
Java/C# 语言律师喜欢说他们的语言通过值传递引用。这意味着“引用”是在调用函数时复制的对象指针。 同时,在 C++ 中(以及在 Perl 和 PHP 中更动态的形式),引用是某个其他名称(或动态
当我需要实现递归 lambda 时,通常我这样做: auto factorial = [](auto& self, int n) -> int { return n == 0 ? 1 : n
我目前正在研究 DDD ,需要一些启发。 我有两个实体 Temple TempleVariant Temple(听筒)包含基本信息(名称,描述等),并具有n个变体,它们具有技术描述(CAD绘图,尺寸,
在 Grails 中 belongsTo允许一个域类与另一个域类建立级联关系。使用belongsTo时有两种类型的关系:引用和无引用。 Reference 在拥有的对象上创建属性,而 No Refer
我正在使用 AWS 和 Django Rest Framework 开发 Web 应用程序。(Django:v1.8,DRF:v3) 我一直在为 POST 多部分表单请求获取 django.reque
我按照下面的定义公开了 WCF 端点, 当我在 .NET 3.5 中添加“服务引用”时,我们在代理中获得了以下类,这非常好: [Syst
我在玩 constexpr 引用时产生了这种感觉。但问题本身与 constexpr 无关,只是被它揭示。 我们知道有“指向const的指针”,也有“const指针”。顺便说一句,由于后者的使用比前者少
我有 2 种类型的 refences,它们中的每一种都可以正常工作。 我尝试使用每一个并在 project build 中得到相同的结果。 请向我解释 COM 引用和引用之间的区别。 谢谢你。 最佳答
我是一名优秀的程序员,十分优秀!