Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数组作为对象中的属性_Java_Arrays_Class_Reference_Attributes - Fatal编程技术网

Java 数组作为对象中的属性

Java 数组作为对象中的属性,java,arrays,class,reference,attributes,Java,Arrays,Class,Reference,Attributes,我对Java比较陌生,我刚刚学会了这一点 import java.util.Arrays; public class Foo { private int[][] foo; public Foo(int[][] arr) { this.foo = arr; } @Override public String toString() { return Arrays.deepToString(this.foo).replace("],",

我对Java比较陌生,我刚刚学会了这一点

import java.util.Arrays;

public class Foo {

  private int[][] foo;

  public Foo(int[][] arr) {
    this.foo = arr;
  }

  @Override
  public String toString() {
    return Arrays.deepToString(this.foo).replace("],", "],\n");
  }
  
  public static void main(String[] args) {
    
    int[][] p = { { 0, 0 }, { 0, 0 } };
    
    Foo g = new Foo(p.clone()); // doesn't work with p nor p.clone()
    System.out.println(g);
    
    p[0][0] = 1;
    
    System.out.println(g);
    
  }

}
在这里,我创建了一个引用另一个对象的对象,并且我可以从外部修改该对象,因为我有对我刚刚作为参数传递给构造函数的对象的引用

虽然我理解为什么会这样,但这似乎违背了我的直觉。如果我将某些内容保存为对象的属性,我希望该对象有一个外部无法访问的“私有”副本

我尝试了
.clone()
,但没有解决它。所以问题是

这通常是怎么做的?我是否需要在构造函数中为循环编写一些
,以从参数中获取每个值

(或者这不是问题?)
问题的最后一部分很重要,可能这不是问题。还是人们做了一些“事情”(通过一些循环来获得深度克隆)?

这里的问题是java实际上没有二维数组。这:

int[][] x;
是一个int数组数组。它不是2D int数组,当然int数组数组的数组确实感觉很像2D数组。对于大多数意图和目的,它是一个2D int数组,除非它不是,而对于clone,它不是。数组的
clone()
impl生成一个新数组,并将每个值逐字复制到新数组中。这意味着您的int数组已克隆,但内部int数组未克隆

当将
int[][]
视为“这是一个2D数组”时,是的,这是不直观的。当将
int[][]
视为“int数组的数组”时,这是非常直观的。在克隆时,您不会期望一个arraylist数组也会克隆每个单独的arraylist


苏。。如何深度克隆阵列阵列(阵列阵列阵列)?有关许多选项,请参见:)

什么不起作用?你问题中的“这个”是什么?嗯,“反直觉”是相对的。对于数组,大多数语言都是这样工作的。否则你的开销会很大。对于Java对象和数组,传递引用。如果您想要一个副本,您需要创建一个副本。@kai我的问题是,这是否是一个问题(或者可能不是),以及通常如何从引用中设置私有属性(是否复制,或者假设外部不会有任何问题)?@Manuel如果没有必要,则“通常”不执行。有关如何进行深度复制,请参阅其他评论中的链接(很好的解释!)。@Manuel请参阅Spara的第二条评论。该链接问题的标题应该更改,因为有n维深度复制数组的选项。您能否回答这通常不是问题,或者人们通常如何将数组分配给属性?或者[a]数组很小,您可以对其进行深度复制,或者更可能找到比数组更合适的数据类型—一种不可变的数据类型,无需防御性复制。(正确的数据类型取决于数组所代表的内容。如果它代表一个游戏板,也许可以创建一个名为board的类。它内部有一个int[][],但您不能修改它,因此您可以随意传递棋盘的副本)。或者,[B]它是一个相当大的阵列,在这种情况下,您确实不想制作防御副本。