这里需要克隆吗?

时间:2012-04-11 11:48:23

标签: java clone findbugs

Findbugs向我发出public GsmSignalStrength clone()警告: 类定义clone()但不实现Cloneable。

为什么我必须实现Cloneable?是因为浅而深的副本?我不得不为我糟糕的Java技能道歉,但我是一个Java新手。

这是我的代码:

class GsmSignalStrength
{
    static final byte SIGNAL_STRENGTH_UNKNOWN = 99;
    static final byte SIGNAL_STRENGTH_1 = 1;
    static final byte SIGNAL_STRENGTH_2 = 2;
    static final byte SIGNAL_STRENGTH_3 = 3;
    static final byte SIGNAL_STRENGTH_4 = 4;
    static final byte SIGNAL_STRENGTH_5 = 5;

    /* Constructors */

    GsmSignalStrength(byte signalStrength)
    {
        initClassVars(signalStrength);
    }

    GsmSignalStrength()
    {
        initClassVars(SIGNAL_STRENGTH_UNKNOWN);
    }

    GsmSignalStrength(byte[] serializedData, IntClass deserializationIndex)
    {
        initClassVars(SIGNAL_STRENGTH_UNKNOWN);
        setClassProperties(serializedData, deserializationIndex);
    }

    byte value;

    /* Methods */

    public void copyTo(GsmSignalStrength destination)
    {
        destination.value = this.value;
    }

    public GsmSignalStrength clone()
    {
        GsmSignalStrength clonedValue = new GsmSignalStrength();

        this.copyTo(clonedValue);

        return clonedValue;
    }

    private void initClassVars(byte signalStrength)
    {
        this.value = signalStrength;
    }
}

3 个答案:

答案 0 :(得分:3)

您可以阅读documentation

  

一个类实现了Cloneable接口,以向Object.clone()方法指示该方法合法地为该类的实例创建一个字段的副本。

     

在未实现Cloneable接口的实例上调用Object的clone方法会导致抛出CloneNotSupportedException异常。

但是,您没有以正确的方式使用clone()方法。看看这个wiki page

答案 1 :(得分:3)

Cloneable此处不需要

这是因为clone()的实现实际上并不克隆该对象。在Java中,克隆特别意味着使用Object.clone(),它使用JVM魔法来复制对象。虽然你的代码做了一些等同于克隆的东西(更好的是,恕我直言 - 它避免使用魔法),但这不是真正的克隆。

但是,并不知道,所以它担心您可能会尝试克隆非Cloneable对象。

此处的一个解决方案可能是将您的方法重命名为其他内容(copy()?),因此它似乎不是克隆。

答案 2 :(得分:1)

如果您将克隆实现为

public GsmSignalStrength clone()
{
    try{
    GsmSignalStrength clonedValue = (GsmSignalStrength )super.clone();

    this.copyTo(clonedValue);
    return clonedValue;
    }catch(CloneNotSupportedException e){thrown new RunTimeException(e);}

}

(如果您要将GsmSignalStrength子类化,则需要根据Object.clone()的文档

super.clone调用将抛出CloneNotSupportedException