clone() and the Cloneable Interface in Java

转自:http://www.java-samples.com/showtutorial.php?tutorialid=344


Most of the methods defined by Object are discussedelsewhere in this book. However, one deserves special attention: clone( ). The clone( )method generates a duplicate copy of the object on which it is called. Only classes that implementthe Cloneable interface can be cloned.

The Cloneable interface defines no members. It is used toindicate that a class allows a bitwise copy of an object (that is, a clone) to be made.If you try to call clone( ) on a class that does not implement Cloneable, a CloneNotSupportedExceptionis thrown. When a clone is made, the constructor for the object being cloned is notcalled. A clone is simply an exact copy of the original.

Cloning is a potentially dangerous action, because it can causeunintended side effects. For example, if the object being cloned contains a referencevariable called obRef, then when the clone is made, obRef in the clone will refer tothe same object as does obRef in the original. If the clone makes a change to the contents of theobject referred to byobRef, then it will be changed for the original object, too.Here is another example. If an object opens an I/O stream and is then cloned, two objects willbe capable of operating on the same stream. Further, if one of these objects closes thestream, the other object might still attempt to write to it, causing an error.

Because cloning can cause problems, clone( ) is declaredas protected inside Object. This means that it must either be called from within a methoddefined by the class that implements Cloneable, or it must be explicitly overriddenby that class so that it is public. Let's look at an example of each approach.

The following program implements Cloneable and definesthe method cloneTest( ), which calls clone( ) in Object:

// Demonstrate the clone() method.
class TestClone implements Cloneable {
int a;
double b;
// This method calls Object's clone().
TestClone cloneTest() {
try {
// call clone in Object.
return (TestClone) super.clone();
} catch(CloneNotSupportedException e) {
System.out.println("Cloning not allowed.");
return this;
}
}
}

class CloneDemo {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
x2 = x1.cloneTest(); // clone x1
System.out.println("x1: " + x1.a + " " +x1.b);
System.out.println("x2: " + x2.a + " " +x2.b);
}
}

Here, the method cloneTest( ) calls clone( ) in Objectand returns the result. Notice that the object returned by clone( ) must be cast into itsappropriate type (TestClone). The following example overrides clone( ) so that it canbe called from code outside of its class. To do this, its access specifier must be public,as shown here:

// Override the clone() method.
class TestClone implements Cloneable {
int a;
double b;
// clone() is now overridden and is public.
public Object clone() {
try {
// call clone in Object.
return super.clone();
} catch(CloneNotSupportedException e) {
System.out.println("Cloning not allowed.");
return this;
}
}
}

class CloneDemo2 {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
// here, clone() is called directly.
x2 = (TestClone) x1.clone();
System.out.println("x1: " + x1.a + " " +x1.b);
System.out.println("x2: " + x2.a + " " +x2.b);
}
}

The side effects caused by cloning are sometimes difficult tosee at first. It is easy to think that a class is safe for cloning when it actually is not. Ingeneral, you should not implementCloneable for any class without good reason.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值