创建并返回同一对象的副本

Creating and returning a copy of the same object

在此class Coord 中,方法public Coord copy() 应该创建和return 一个新的Coord 值,其具有与当前对象相同的row/column 表示。为什么在我制作 this = clone 时出现错误?

public class Coord {

    public final int r;
    public final int c;


    public Coord(int r, int c)
    {
        this.r = r;
        this.c = c;
    }

    public Coord step(Direction d)
    {
        if(d == Direction.N)
        {
            Coord newValue = new Coord(r + 1, c);
            return newValue;
        }
        else if(d == Direction.S)
        {
            Coord newValue = new Coord(r - 1, c);
            return newValue;
        }
        else if(d == Direction.E)
        {
            Coord newValue = new Coord(r, c + 1);
            return newValue;
        }
        else if(d == Direction.W)
        {
            Coord newValue = new Coord(r, c - 1);
            return newValue;
        }

        else
            return this;

    }

    public Coord copy()
    {
        Coord clone = new Coord(r, c);
        this = clone;
        return clone;

    }


}

我想你想这样做:

public Coord copy() {
    Coord clone = new Coord(r, c);
    return clone;
}

在这种情况下,甚至可以缩短为:

public Coord copy() {
    return new Coord(r, c);
}

this keyword 是对当前对象(在本例中为当前 Coord 对象)的引用,并且 Java 不允许您将新值分配给this。如果你想制作一个副本,那么你只需要创建你的新对象和return那个新对象。


也许这样想会有所帮助。

您可能正在使用 Coordcopy() 方法来制作副本:

int x = ...; //x is some int
int y = ...; //y is some int

Coord coordOriginal = new Coord(x, y);
//coordOriginal points to a new Coord object. Let's call it "A".

Coord coordCopy = coordOriginal.copy();
//coordCopy points to to a new Coord object.  Let's call it "B".
//coordOriginal still points to Coord object "A".

如果 copy() 正常工作,您会期望 coordOriginalcoordCopy 指向 两个不同的 对象。 coordOriginal指向Coord对象AcoordCopy指向Coord对象B .

现在假设您可以像在示例代码的 copy() 方法中那样为 this 分配一个新值:

//in this case, "this" points to object "A".
public Coord copy()
{
    //creates an object "B"
    Coord clone = new Coord(r, c);

    //***overwrites object "A" with object "B"!***
    this = clone;

    //returns object "B"
    return clone;
}
//object "A" gets garbage collected?

所以你看,如果你可以在你的 copy() 方法中将一个新对象分配给 this(而 Java 不会让你),你将改变原来的对象Coord 反对,而你只想复制一份!


如问题评论中所述,另一种方法是制作复制构造函数:

public class Coord {

    public final int r;
    public final int c;

    public Coord(int r, int c) {
        this.r = r;
        this.c = c;
    }

    //copy constructor
    public Coord(Coord other) {
        this(other.r, other.c);
    }

}

然后你可以这样复制:

int x = ...; //x is some int
int y = ...; //y is some int

Coord coordOriginal = new Coord(x, y);
Coord coordCopy = new Coord(coordOriginal);

首先this是关键字而不是变量,所以赋值给关键字没有意义。

在第二种情况下,你不能分配给 this 因为在 Java 中它是被禁止的,this 指的是你调用当前方法的对象,虽然这在技术上可能是可行的,这是不允许的。

要获得同样的东西,您必须从方法外部或通过访问容器将对象的存储位置重新分配给新创建的 Coord。另一种方法是直接修改对象本身的成员变量,但这不是一回事。