覆盖克隆时处理最终字段

Dealing with final fields when overriding clone

我正在写一个 class,其中我必须用臭名昭著的 "super.clone() strategy" 覆盖 clone() 方法(这不是我的选择)。

我的代码如下所示:

@Override
public myInterface clone()
{
    myClass x;
    try
    {
        x = (myClass) super.clone();
        x.row = this.row;
        x.col = this.col;
        x.color = this.color; 
        //color is a final variable, here's the error
    }
    catch(Exception e)
    {
        //not doing anything but there has to be the catch block
        //because of Cloneable issues
    }
    return x;
}

一切都会好起来的,除了我无法在不使用构造函数的情况下初始化 color,因为它是最终变量...有没有办法同时使用 super.clone() 和复制最终变量?

假设您没有其他选择,您可以使用反射。以下代码显示了它如何分叉字段颜色。 你需要尝试抓住它。

Field f =  getClass().getDeclaredField("color");
f.setAccessible(true);
f.set(x, this.color)

由于对 super.clone(); 的调用已经创建了所有字段的(浅)副本,无论最终与否,您的完整方法将变为:

@Override
public MyInterface clone() throws CloneNotSupportedException {
    return (MyInterface)super.clone();
}

这需要 superclass 也正确实现 clone()(以确保 super.clone() 最终到达 Object class。所有字段将被正确复制(包括最终的),如果你不需要深度克隆或任何其他特殊功能,你可以使用它然后保证你永远不会再次尝试实现 clone() (其中之一原因是正确实施它并不容易,从这个问题可以看出)。