Java 复制到这里?

Java 复制到这里?,java,Java,考虑以下情况: 我为嵌入式(调制解调器)设备编写了一个java程序。SDK不提供可克隆性。 因此,我在类GsmSignalStrength中有方法clone(),但它不是 从Object.clone(),它是“我的”实现。 我想知道这是否有用且正确,或者我应该在GsmSignalStrength中使用复制构造函数,就像在注释中一样? 我不认为复制构造函数有什么好处,因为我必须在状态机中创建另一个GsmSignalStrength对象 这是我的密码 文件1“Status.java”: 文件2“Gs

考虑以下情况:

我为嵌入式(调制解调器)设备编写了一个java程序。SDK不提供可克隆性。 因此,我在
类GsmSignalStrength
中有方法
clone()
,但它不是 从
Object.clone()
,它是“我的”实现。 我想知道这是否有用且正确,或者我应该在
GsmSignalStrength
中使用复制构造函数,就像在注释中一样? 我不认为复制构造函数有什么好处,因为我必须在状态机中创建另一个GsmSignalStrength对象

这是我的密码

文件1“Status.java”:

文件2“GsmSignalStrength”:

文件5“GsmModemHandler”:

文件4“状态机”:

你在评论中所说的

GsmSignalStrength(GsmSignalStrength gsmSignalStrength)
    {
        gsmSignalStrength = this;
    }
不是复制构造函数。线路

gsmSignalStrength = this;
没有任何效果,因为它所做的只是将一个方法本地引用移动到

功能正常的“复制构造函数”类似于

GsmSignalStrength(GsmSignalStrength gsmSignalStrength)
    {
        this.value = gsmSignalStrength.value;
    }
要点是创建一个独立的对象,其成员变量与原始对象相同

也不同于C++,编写

object1 = object2;
不调用复制构造函数。它所做的只是复制引用——最终会有两个引用指向同一个对象。 如果要创建新对象,必须显式调用构造函数:

object1 = new GsmSignalStrength( object2 );

至于它是否“无用”,则取决于您的应用程序。复制构造函数、
clone()
方法和您的
copyTo
方法都完成相同的基本任务。您可以使用构造函数创建一个新对象,或者使用
clone()
,或者创建一个新对象并在其上使用
copyTo
——选择一种方法来做您想做的事情并坚持使用它。

您在该注释中的内容

GsmSignalStrength(GsmSignalStrength gsmSignalStrength)
    {
        gsmSignalStrength = this;
    }
不是复制构造函数。线路

gsmSignalStrength = this;
没有任何效果,因为它所做的只是将一个方法本地引用移动到

功能正常的“复制构造函数”类似于

GsmSignalStrength(GsmSignalStrength gsmSignalStrength)
    {
        this.value = gsmSignalStrength.value;
    }
要点是创建一个独立的对象,其成员变量与原始对象相同

也不同于C++,编写

object1 = object2;
不调用复制构造函数。它所做的只是复制引用——最终会有两个引用指向同一个对象。 如果要创建新对象,必须显式调用构造函数:

object1 = new GsmSignalStrength( object2 );


至于它是否“无用”,则取决于您的应用程序。复制构造函数、
clone()
方法和您的
copyTo
方法都完成相同的基本任务。您可以使用构造函数创建一个新对象,或者使用
clone()
,或者创建一个新对象并在其上使用
copyTo
——选择一种方法来做您想做的事情并坚持使用它。

我认为您应该使用clone,但要小心。 Joshua Bloch的高效Java声明您应该明智地使用克隆,因为它是一个弱接口,并且没有提供支持该活动的方法契约。您还依赖于行为良好的超类克隆行为(也就是说,超类使用
super#clone
而不是使用类构造函数来创建对象(这将创建错误的类).注意,这就是您在文件2示例中所做的-在非final类中,您将破坏任何克隆子类

请注意,您的克隆(以及每个超类克隆)应提供所有IVAR的完整副本。现在请注意,您可能需要制作数组和列表等内容的深度副本,也就是说,创建数组的新实例并在您自己的列表中添加元素的新副本。这是“深度副本”,而不是“浅层副本”。克隆不应与原始对象共享相同的数据(尽管您可能会根据具体情况对此进行讨论)

此外,我不认为复制构造函数的概念有任何错误,只要它有很好的文档证明了你的复制是做什么的(例如,深度复制和浅层复制)

示例的示例代码如下:

public class GSMSignalStrength implements Cloneable {
    ...
    public Object clone() throws CloneNotSupportedException {
        GSMSignalStrength result = (GSMSignalStrength)super.clone();
        result.setValue(this.value);
        result.setAnyOldArray(this.deepCopyMyAnyOldArray());
        ...
    }
    ...
}
希望这有帮助


p、 在过去(Obj-C world,我们在图形包中做了很多cop构造,并与我们的对象图紧密联系在一起——何时进行深度复制,何时进行浅复制).V.复杂。

我认为你应该使用克隆,但要小心。 Joshua Bloch的高效Java指出,您应该明智地使用克隆,因为它是一个弱接口,并且不提供任何方法契约来支持活动。您还依赖于行为良好的超类克隆行为(即,超类使用
super#clone
,而不是使用类构造函数来创建对象(这将创建一个错误的类)。请注意,这是您在文件2示例中所做的。-在非final类中,您将破坏任何克隆子类

请注意,您的克隆(以及每个超类克隆)应提供所有IVAR的完整副本。现在请注意,您可能需要制作数组和列表等内容的深度副本,也就是说,创建数组的新实例并在您自己的列表中添加元素的新副本。这是“深度副本”,而不是“浅层副本”。克隆不应与原始对象共享相同的数据(尽管您可能会根据具体情况对此进行讨论)

此外,我不认为复制构造函数的概念有任何错误,只要它有很好的文档证明了你的复制是做什么的(例如,深度复制和浅层复制)

示例的示例代码如下:

public class GSMSignalStrength implements Cloneable {
    ...
    public Object clone() throws CloneNotSupportedException {
        GSMSignalStrength result = (GSMSignalStrength)super.clone();
        result.setValue(this.value);
        result.setAnyOldArray(this.deepCopyMyAnyOldArray());
        ...
    }
    ...
}
希望这有帮助

p、 在过去(Obj-C世界中,我们在图形包中做了很多cop构造,并与我们的对象图捆绑在一起)-