ecl*_*eel 30
使用Copy Constructor的另一个选项(来自Java Practices):
public final class Galaxy {
public Galaxy (double aMass, String aName) {
fMass = aMass;
fName = aName;
}
/**
* Copy constructor.
*/
public Galaxy(Galaxy aGalaxy) {
this(aGalaxy.getMass(), aGalaxy.getName());
//no defensive copies are created here, since
//there are no mutable object fields (String is immutable)
}
/**
* Alternative style for a copy constructor, using a static newInstance
* method.
*/
public static Galaxy newInstance(Galaxy aGalaxy) {
return new Galaxy(aGalaxy.getMass(), aGalaxy.getName());
}
public double getMass() {
return fMass;
}
/**
* This is the only method which changes the state of a Galaxy
* object. If this method were removed, then a copy constructor
* would not be provided either, since immutable objects do not
* need a copy constructor.
*/
public void setMass( double aMass ){
fMass = aMass;
}
public String getName() {
return fName;
}
// PRIVATE /////
private double fMass;
private final String fName;
/**
* Test harness.
*/
public static void main (String... aArguments){
Galaxy m101 = new Galaxy(15.0, "M101");
Galaxy m101CopyOne = new Galaxy(m101);
m101CopyOne.setMass(25.0);
System.out.println("M101 mass: " + m101.getMass());
System.out.println("M101Copy mass: " + m101CopyOne.getMass());
Galaxy m101CopyTwo = Galaxy.newInstance(m101);
m101CopyTwo.setMass(35.0);
System.out.println("M101 mass: " + m101.getMass());
System.out.println("M101CopyTwo mass: " + m101CopyTwo.getMass());
}
}
Run Code Online (Sandbox Code Playgroud)
Ron*_*hke 20
有两种流行的方法.一个是提供clone
你提到的方法,就像这样.
public class C implements Cloneable {
@Override public C clone() {
try {
final C result = (C) super.clone();
// copy fields that need to be copied here!
return result;
} catch (final CloneNotSupportedException ex) {
throw new AssertionError();
}
}
Run Code Online (Sandbox Code Playgroud)
注意"复制字段......在这里!" 部分.初始result
只是一个浅拷贝,这意味着如果有一个对象的引用,原始和result
将共享同一个对象.例如,如果C
包含,private int[] data
您可能想要复制它.
...
final C result = (C) super.clone();
result.data = data.clone();
return result;
...
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要复制原始字段,因为它们的内容已被复制,或者不可变对象,因为它们无论如何都无法更改.
第二种方法是提供复制构造函数.
public class C {
public C(final C c) {
// initialize this with c
}
}
Run Code Online (Sandbox Code Playgroud)
或者是复印厂.
public class C {
public static C newInstance(final C c) {
return new C(c);
}
private C(final C c) {
// initialize this with c
}
}
Run Code Online (Sandbox Code Playgroud)
两种方法都有各自的属性. clone
很好,因为它是一个方法,所以你不必知道确切的类型.最后,你应该总是得到一个"完美"的副本.复制构造函数很好,因为调用者有机会决定,Java Collections可以看到.
final List c = ...
// Got c from somewhere else, could be anything.
// Maybe too slow for what we're trying to do?
final List myC = new ArrayList(c);
// myC is an ArrayList, with known properties
Run Code Online (Sandbox Code Playgroud)
我建议选择哪种方法,哪一种更适合你.
我只在单元测试中使用其他方法,如反射复制或立即序列化/反序列化.对我来说,他们觉得不太适合生产代码,主要是因为性能问题.
Yon*_*oit 14
一些选择:
Cloneable
为您的对象实现并将clone()
方法设置为公共.请参阅此处的完整说明:http://www.cafeaulait.org/course/week4/46.htmlSerializable
为对象及其所有字段实现接口.XStream
XML来执行序列化 - 您不必在此处实现任何内容. 归档时间: |
|
查看次数: |
70721 次 |
最近记录: |