无法理解下面的代码中发生了什么。阵列的行为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
and
的可交换性d
表示值传递:Java是值传递,该死!。(我还查看了按引用传递的java数组不起作用?,但我听不懂asker的英文,方法调用使示例变得晦涩。)
请注意,与线d = tmp;
注释,c
并d
表现出相同的奇数行为a
和b
。仍然我不知道该怎么做。
谁能解释如何 通过值传递来解释a
和b
的行为?
事实证明,我帖子中的主要问题不是按值传递,而是混叠。要明确传递的价值和指针之间的区别,我添加了下面的方法来我的代码,并用它(试图)交换c
,并d
(通过建议文章通过JavaDude的文章上面链接的链接)。
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;
此处描述的相对时间。
这里没有任何“怪异”现象:数组变量是 对 实际数组的 引用 (在其他语言中也称为指针)。当您操纵数组变量时,您要做的就是操纵指针。
当您将一个数组变量分配给另一个变量时,将为您分配的变量所指向的数组创建一个 别名 ,并使先前被分配的变量所指向的数组符合垃圾回收的条件。由于分配a = b
,使a
一个别名b
,填充b
数据的行为完全一样的填充a
数据:一旦分配完成,a
而b
仅仅是同一事物的两个不同的名字。
就 按值传递
而言,在您的示例中没有任何作用:按值传递的概念仅在将对象作为参数传递给调用的方法时适用。在你的例子,变量a
,b
,c
,和d
是不是方法的参数,它们是局部变量。你做参考方法,通过他们toString
和fill
(或者更准确地说,按值引用传递给你的对象toString
和fill
,因为在Java一切都是按值传递),这就是为什么修改您的阵列将完成fill
须待返回可见从方法。
问题内容: 我一直在玩Go制作一些数据结构库,这是一个大问题。我希望数据结构能够包含任何类型,但是在Go中我看不到任何方法可以执行此操作,因为您无法声明空指针,并且它们没有像NSObject这样的类,所有对象都可以从中继承。如何在Go中实现相同的功能? 问题答案: 根据Go编程语言规范: 类型实现包含其方法的任何子集的任何接口,因此可以实现几个不同的接口。例如,所有类型都实现 空接口 : 如果您在
问题内容: 为什么这样做有效: 但这不是: 如果我有一个数组实例变量,并且想在我的构造函数中对其进行初始化,那么我不必走 我觉得我在这里想念什么吗? 问题答案: 这里的构造在Java中称为数组初始化器。这是一个特殊的速记,仅在某些语法构造中可用: [JLS 10.6数组初始化器](http://java.sun.com/docs/books/jls/third_edition/html/array
问题内容: 因此,在C#中,我可以将a 视为。 是否有Java等效项? 问题答案: 等于。 如果实现数组,在类型系统中将是一个奇怪的现象。是的实例,但不是。类和接口不能乘以不同的通用参数来实现相同的通用接口。 将像增强的for循环中的一样工作。 可以很容易地变成: 优先于数组而不是集合(对于非基本类型而言)。引用类型的数组有点奇怪,自Java 1.5开始很少使用。
问题内容: 基本上,我希望每10毫秒调用一次函数。 如何在Java中实现? 问题答案: 您可能想看看Timer。
问题内容: 我有一个大数组和一个将索引列表返回到数组的函数,即 典型的情况是范围是整个数组。不幸的是,使用while进行缩放当然是固定时间的。可惜一个人不能从那里回来。 我可以从中返回什么用作整个数组的索引? 问题答案: NumPy有一个可用于构造和对象的助手: 一般而言,与完全相同。
问题内容: 在C#中寻找与此方法相同的方法 问题答案: 在C#中超级简单: