【问题标题】:Array as attribute in an object [duplicate]数组作为对象中的属性[重复]
【发布时间】:2019-06-28 08:32:52
【问题描述】:

我对 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() 并没有解决它。所以问题是……

这通常是怎么做的?我是否需要在构造函数中编写几个for 循环来获取参数中的每个值?

 (或者这不是问题?)

问题的最后一部分很重要,可能这不是问题。还是人们做“某事”(几个循环来获得深度克隆)?

【问题讨论】:

  • 什么不起作用?您的问题中的“这个”是什么?
  • 好吧,“违反直觉”是相对的。对于数组,大多数语言都是这样工作的。否则你会得到巨大的开销。对于 Java 对象和数组,引用被传递。如果你想要一个副本,你需要创建一个。
  • @kai 我的问题是这是否是一个问题(或者可能不是)以及通常如何从引用中设置私有属性(人们进行深度复制,或者假设不会外面有什么问题吗?
  • @Manuel 如果没有必要,“通常”不会这样做。有关如何进行深层复制,请参阅其他 cmets 中的链接(很好的解释!)。
  • @Manuel 见 Spara 的第二条评论。

标签: java arrays class reference attributes


【解决方案1】:

这里的问题是 java 并没有真正的二维数组。这个:

int[][] x;

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

当将int[][] 视为“这是一个二维数组”时,是的,这是不直观的。将int[][] 视为“int 数组的数组”时,它非常直观。你不会期望一个数组列表在克隆时也会克隆每个单独的数组列表。

Soo.. 你如何深度克隆一个数组数组(数组的数组)?更多选项请参见How do I do a deep copy of a 2d array in Java? :)

【讨论】:

  • 应该更改链接问题的标题,因为可以选择深度复制 n 维数组。如果这通常不是问题,或者人们通常如何将数组分配给属性,您能否也回答一下?
  • 好吧,要么 [A] 数组很小,你要么对其进行深度复制,要么更有可能找到比数组更可口的数据类型——一种不可变的数据类型,无需防御副本。 (正确的数据类型取决于数组所代表的内容。如果它代表一个游戏板,也许创建一个名为 Board 的类。它在内部有一个 int[][],但你不能修改它,所以你可以传递董事会的副本随意)。或者,[B] 它是一个相当大的数组,在这种情况下你真的不想制作防御性副本。
猜你喜欢
  • 1970-01-01
  • 2016-03-22
  • 2020-03-04
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2018-10-18
相关资源
最近更新 更多