Object文档中指出对象需要被clone,则需要实现Cloneable接口。Cloneable接口只是个标记,没有任何方法。
对于任何对象x, - x.clone() != x返回为true - x.clone().getClass() == x.getClass()返回为true - x.clone().equals(x)返回为true
但是约定同时指出,这些都不是绝对必须的
所以一般在开发中,很少使用clone方法。另在《阿里巴巴Java开发手册》中,有条建议:【推荐】慎用Object的clone方法来拷贝对象。因此在日常开发中,我们应该尽量避免采用clone的方法。
常替换的方法有: 1. 拷贝构造器
public class PhoneNumber { private short areaCode; private short prefix; private short lineNumber; public PhoneNumber(int areaCode, int prefix, int lineNumber) { rangeCheck(areaCode, 999, "area code"); rangeCheck(prefix, 999, "prefix"); rangeCheck(lineNumber, 9999, "line number"); this.areaCode = (short) areaCode; this.prefix = (short) prefix; this.lineNumber = (short) lineNumber; } //拷贝构造器 public PhoneNumber(PhoneNumber phoneNumber) { this.areaCode = phoneNumber.getAreaCode(); this.prefix = phoneNumber.getPrefix(); this.lineNumber = phoneNumber.getLineNumber(); } private static void rangeCheck(int arg, int max, String name) { if (arg < 0 || arg > max) { throw new IllegalArgumentException(name + ": " + arg); } } public short getAreaCode() { return areaCode; } public void setAreaCode(short areaCode) { this.areaCode = areaCode; } public short getPrefix() { return prefix; } public void setPrefix(short prefix) { this.prefix = prefix; } public short getLineNumber() { return lineNumber; } public void setLineNumber(short lineNumber) { this.lineNumber = lineNumber; } } 拷贝工厂 public class PhoneNumber { private short areaCode; private short prefix; private short lineNumber; public PhoneNumber(int areaCode, int prefix, int lineNumber) { rangeCheck(areaCode, 999, "area code"); rangeCheck(prefix, 999, "prefix"); rangeCheck(lineNumber, 9999, "line number"); this.areaCode = (short) areaCode; this.prefix = (short) prefix; this.lineNumber = (short) lineNumber; } //拷贝工厂方法 public static PhoneNumber newInstance(PhoneNumber phoneNumber) { return new PhoneNumber(phoneNumber.getAreaCode(), phoneNumber.getPrefix(), phoneNumber.getLineNumber()); } private static void rangeCheck(int arg, int max, String name) { if (arg < 0 || arg > max) { throw new IllegalArgumentException(name + ": " + arg); } } public short getAreaCode() { return areaCode; } public void setAreaCode(short areaCode) { this.areaCode = areaCode; } public short getPrefix() { return prefix; } public void setPrefix(short prefix) { this.prefix = prefix; } public short getLineNumber() { return lineNumber; } public void setLineNumber(short lineNumber) { this.lineNumber = lineNumber; } }