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