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

我偶然发现了一个问题,我必须创建一个方法,该方法不接受输入并返回此篮子的 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;

    }


holdtom
浏览 113回答 2
2回答

小怪兽爱吃肉

如果它是浅拷贝那么它就是引用的副本吗?不,它是一个新数组,包含对与原始数组相同的对象的引用我可以对java中的任何对象使用clone方法吗?Object.clone()不。阅读和的 javadocCloneable以了解规则。如果是这样,那么可以简化以下内容(而不是使用 for 循环,我可以使用克隆?)?不,因为clone()会给你一个相同长度的新数组,因此你将无法在数组末尾添加新元素。

拉莫斯之舞

如果它是浅拷贝那么它就是引用的副本吗?不,它是对具有该对象属性副本的新对象的新引用。细节取决于clone.我可以对java中的任何对象使用clone方法吗?它复制引用还是实际对象?首先,clone不是用于数组浅表复制的正确工具。您可以改用System.arraycopy。在您的情况下,您会在末尾为新条目分配一个带有空间的数组,然后将arraycopy原始条目分配给它,然后添加您的条目。public&nbsp;void&nbsp;add(MarketProduct&nbsp;input)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;MarketProduct[]&nbsp;list&nbsp;=&nbsp;new&nbsp;MarketProduct[marketproducts.length&nbsp;+&nbsp;1]; &nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(marketproducts,&nbsp;0,&nbsp;list,&nbsp;0,&nbsp;marketproducts.length); &nbsp;&nbsp;&nbsp;&nbsp;list[list.length-1]&nbsp;=&nbsp;input;&nbsp;&nbsp;&nbsp;&nbsp;this.marketproducts&nbsp;=&nbsp;list; }显然这有点贵,您可能会考虑使用其中一个List类(也许ArrayList),这样您就不会每次都增加数组。重新clone,请参阅JavaDoc:创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类。一般意图是,对于任何对象x,表达式:&nbsp;x.clone()&nbsp;!=&nbsp;x将是真实的,并且表达式:&nbsp;x.clone().getClass()&nbsp;==&nbsp;x.getClass()会true,但这些都不是绝对要求。虽然通常情况是:&nbsp;x.clone().equals(x)会true,这不是绝对要求。按照约定,返回的对象应该通过调用&nbsp;super.clone.&nbsp;如果一个类及其所有超类(除了&nbsp;Object)都遵守这个约定,那么&nbsp;x.clone().getClass() == x.getClass().按照惯例,此方法返回的对象应该独立于此对象(正在被克隆)。为了实现这种独立性,可能需要在super.clone返回之前修改返回对象的一个或多个字段。通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并将对这些对象的引用替换为对副本的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下返回的对象中没有字段需要super.clone&nbsp;修改。clone类的&nbsp;方法Object执行特定的克隆操作。首先,如果这个对象的类没有实现接口Cloneable,那么&nbsp;CloneNotSupportedException抛出一个。请注意,所有数组都被视为实现接口,并且数组类型方法的Cloneable返回类型&nbsp;是其中 T 是任何引用或原始类型。否则,此方法会创建此对象类的新实例,并使用此对象相应字段的内容来初始化其所有字段,就像通过赋值一样;字段的内容本身不是克隆的。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。&nbsp;cloneT[]T[]该类Object本身不实现该接口&nbsp;Cloneable,因此clone在其类是的对象上调用该方法Object将导致在运行时抛出异常。所以你不能在没有实现的对象上使用它Cloneable,但你可以在实现的对象上使用它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java