Java,这是一个Deep副本吗?

Sno*_*ama 7 java deep-copy

我似乎无法通过阅读任何类似的问题得到一个明确的精确答案,我正在尝试使用复制构造函数深入克隆Java中的对象这是一个深层副本:

public class Tile{
    Image sprite = null;
    int x = 0;
    int y = 0;
    public Tile(Image setImage, int sX, int sY){
         this.sprite = setImage;
         this.x = sX;
         this.y = sY;
    }
    public Tile(Tile copyTile){
         this.sprite = copyTile.sprite;
         this.x = copyTile.x;
         this.y = copyTile.y;
    }
    public void setNewLocation(int sX, int sY){
         this.x = sX;
         this.y = sY;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当我创建我的瓷砖地图时,我可以做这样的事情

List<Tile> tileList = new List<Tile>();
Tile masterGrassTile = new Tile(grassImage, 0,0);
tileList.set(0,new Tile(masterGrassTile));
tileList.set(1,new Tile(masterGrassTile));
tileList.get(0).setNewLocation(0,32);
tileList.get(1).setNewLocation(0,64);
Run Code Online (Sandbox Code Playgroud)

如果我要在各自的位置渲染两块瓷砖那会有用吗?或者是赋值tileList.get(1).setNewLocation(0,64); 影响像引用,所有这些都与上次分配的位置相同.

Sub*_*Sao 11

这是一份深刻的副本吗?

不,这不是因为this.sprite = copyTile.sprite;两个对象Tile都是指同一个对象Image.

如果我要在各自的位置渲染两块瓷砖那会有用吗?或者是赋值tileList.get(1).setNewLocation(0,64); 影响像引用,所有这些都与上次分配的位置相同.

不,x和y的值在两个对象中是独立的,Tiles并且代码应该起作用,并且两个对象将具有不同的x和y值.


Kev*_*sox 4

首先,让我们回顾一下深拷贝和浅拷贝之间的区别。

浅拷贝指向与源相同的引用。因此,如果创建名为实例的副本,则对包含对象的字段进行任何更改A都会修改这些字段,因为它们指向相同的引用。BBA

深层副本具有独立的字段/引用,它不指向源的引用。对副本上的字段/属性的更改不会影响源的字段/属性。

就您而言,我相信您已经制作了浅表副本,因为您将精灵字段的引用从源分配到副本的精灵字段。

为了说明这一点,我修改了Tile类源以公开Image并模拟了一个Image类。

概念验证的修改

class Tile{
        /* Rest of Class*/
        //Additions
    public Image getSprite() {
        return sprite;
    }
    public void setSprite(Image sprite) {
        this.sprite = sprite;
    }

}

//Mock
class Image{
    public String name;
    public Image(String name){
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

概念验证

public static void main(String[] args) {
    List<Tile> tileList = new ArrayList<Tile>();
    Tile masterGrassTile = new Tile(new Image("grass.png"), 0,0);

    Tile copyTile = new Tile(masterGrassTile);
    copyTile.getSprite().name = "water.png";

    System.out.println(masterGrassTile.getSprite().name); //Prints water.png
}
Run Code Online (Sandbox Code Playgroud)

请注意更改复制实例的精灵属性如何影响原始实例的精灵属性。