当前位置: 首页 > 面试题库 >

等效Java数组中的怪异:引用与指针

苗森
2023-03-14
问题内容

无法理解下面的代码中发生了什么。阵列的行为c,并d为我所期望的那样。但是,这是怎么回事与ab?(我也使用普通的标量变量进行了此尝试,在任何情况下都不会发生令人惊讶的事情。)

输出被复制到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]
    }
}

根据这篇文章,cand
的可交换性d表示值传递:Java是值传递,该死!。(我还查看了按引用传递的java数组不起作用?,但我听不懂asker的英文,方法调用使示例变得晦涩。)

请注意,与线d = tmp;注释,cd表现出相同的奇数行为ab。仍然我不知道该怎么做。

谁能解释如何 通过值传递来解释ab的行为?

事实证明,我帖子中的主要问题不是按值传递,而是混叠。要明确传递的价值和指针之间的区别,我添加了下面的方法来我的代码,并用它(试图)交换c,并d(通过建议文章通过JavaDude的文章上面链接的链接)。

static <T> void swap (T c, T d) {
    T tmp = c;
    c = d;
    d = tmp;
}

结果就是那样,c并且d保持不变。如果Java(如C)将指针传递给该方法cd指向该方法,那将行得通,而只是传递其值,而使原始变量保持不变。

更改a = ba = 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数据:一旦分配完成,ab仅仅是同一事物的两个不同的名字。

按值传递
而言,在您的示例中没有任何作用:按值传递的概念仅在将对象作为参数传递给调用的方法时适用。在你的例子,变量abc,和d是不是方法的参数,它们是局部变量。你做参考方法,通过他们toStringfill(或者更准确地说,按值引用传递给你的对象toStringfill,因为在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#中超级简单: