为了账号安全,请及时绑定邮箱和手机立即绑定

数组的浅拷贝而不是引用的副本

数组的浅拷贝而不是引用的副本

holdtom 2023-03-09 16:46:07
我偶然发现了一个问题,我必须创建一个方法,该方法不接受输入并返回此篮子的 MarketProduct 数组的浅表副本(不是引用的副本)。我知道解决方案如下public class Basket {    private MarketProduct[] marketproducts;    public Basket() {        this.marketproducts = new MarketProduct[0];    }    public MarketProduct[] getProducts() {        return this.marketproducts.clone();我不明白的是 1. 如果它是浅拷贝那么它就是引用的副本吗?2.我可以对java中的任何对象使用clone方法吗?它复制引用还是实际对象?如果是这样,那么可以简化以下内容(而不是使用 for 循环,我可以使用克隆?)?public void add(MarketProduct input) {        MarketProduct[] list = new MarketProduct[marketproducts.length];        for(int i = 0; i < marketproducts.length; i++) {            list[i] = marketproducts[i];        }        list[list.length-1] = input;        this.marketproducts = list;    }
查看完整描述

2 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

  1. 如果它是浅拷贝那么它就是引用的副本吗?

不,它是一个新数组,包含对与原始数组相同的对象的引用

  1. 我可以对java中的任何对象使用clone方法吗?

Object.clone()不。阅读和的 javadocCloneable以了解规则。

如果是这样,那么可以简化以下内容(而不是使用 for 循环,我可以使用克隆?)?

不,因为clone()会给你一个相同长度的新数组,因此你将无法在数组末尾添加新元素。


查看完整回答
反对 回复 2023-03-09
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

  1. 如果它是浅拷贝那么它就是引用的副本吗?

不,它是对具有该对象属性副本的新对象的新引用。细节取决于clone.

  1. 我可以对java中的任何对象使用clone方法吗?它复制引用还是实际对象?

首先,clone不是用于数组浅表复制的正确工具。您可以改用System.arraycopy。在您的情况下,您会在末尾为新条目分配一个带有空间的数组,然后将arraycopy原始条目分配给它,然后添加您的条目。

public void add(MarketProduct input) {
    MarketProduct[] list = new MarketProduct[marketproducts.length + 1];
    System.arraycopy(marketproducts, 0, list, 0, marketproducts.length);
    list[list.length-1] = input;    this.marketproducts = list;
}

显然这有点贵,您可能会考虑使用其中一个List类(也许ArrayList),这样您就不会每次都增加数组。

重新clone,请参阅JavaDoc

创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类。一般意图是,对于任何对象x,表达式:
 x.clone() != x
将是真实的,并且表达式:
 x.clone().getClass() == x.getClass()
true,但这些都不是绝对要求。虽然通常情况是:
 x.clone().equals(x)
true,这不是绝对要求。

按照约定,返回的对象应该通过调用 super.clone. 如果一个类及其所有超类(除了 Object)都遵守这个约定,那么 x.clone().getClass() == x.getClass().

按照惯例,此方法返回的对象应该独立于此对象(正在被克隆)。为了实现这种独立性,可能需要在super.clone返回之前修改返回对象的一个或多个字段。通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并将对这些对象的引用替换为对副本的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下返回的对象中没有字段需要super.clone 修改。

clone类的 方法Object执行特定的克隆操作。首先,如果这个对象的类没有实现接口Cloneable,那么 CloneNotSupportedException抛出一个。请注意,所有数组都被视为实现接口,并且数组类型方法的Cloneable返回类型 是其中 T 是任何引用或原始类型。否则,此方法会创建此对象类的新实例,并使用此对象相应字段的内容来初始化其所有字段,就像通过赋值一样;字段的内容本身不是克隆的。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。 cloneT[]T[]

该类Object本身不实现该接口 Cloneable,因此clone在其类是的对象上调用该方法Object将导致在运行时抛出异常。

所以你不能在没有实现的对象上使用它Cloneable,但你可以在实现的对象上使用它。


查看完整回答
反对 回复 2023-03-09
  • 2 回答
  • 0 关注
  • 79 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信