`
gabrielcjx
  • 浏览: 32070 次
  • 性别: Icon_minigender_2
  • 来自: 长春
社区版块
存档分类
最新评论

java中的clon()和cloneable接口浅析

    博客分类:
  • java
阅读更多

今天看了一上午关于clone()和cloneable interface 的文章,我推荐一篇供大家参考学习。

蓝色为我的翻译,有不当之处,大家多多包涵!

 

clone() and the Cloneable Interface in Java

 

 

......The clone( ) method generates a duplicate copy of the object on which it is called. Only classes that implement the Cloneable interface can be cloned.


...clone()产生了一个调用它的对象的复制;只有实现了Cloneable接口的类才可以被复制。



The Cloneable interface defines no members. It is used to indicate 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 CloneNotSupportedException is thrown. When a clone is made, the constructor for the object being cloned is not called. A clone is simply an exact copy of the original.


Cloneable 接口没有定义任何成员。它用来指明一个类可以逐位复制一个对象。如果你试图对一个没有实现cloneable接口的类调用clone()方法,一个CloneNotSupportedException 就会抛出。在复制时,被复制的对象的构造器并没有被调用。复制对象就是原来对象的拷贝。


Cloning is a potentially dangerous action, because it can cause unintended side effects. For example, if the object being cloned contains a reference variable called obRef, then when the clone is made, obRef in the clone will refer to the same object as does obRef in the original. If the clone makes a change to the contents of the object referred to by obRef, 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 will be capable of operating on the same stream. Further, if one of these objects closes the stream, the other object might still attempt to write to it, causing an error.

 

复制是一种存在潜在危险的行为,因为它会引起一些意想不到的负作用。例如,如果被复制的对象包含一个名为 obRef 引用变量,在复制时,复制对象的 obRe和f 原来对象的 obRef 都会指向同一个对象。如果复制对象对 obRef 指向的对象的内容做出一些改变,对于原来对象来说,也就相当于它也被改变了。还有另一个例子,如果一个操作I/O流的对象被复制了,这两个对象都能对同一I/O流进行操作。进一步说,如果它们两个中的一个关闭了I/O流,而另一个对象可能试图对I/O流进行写操作,这就会引起错误。


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

因为复制可以引起许多问题,clone()在object类中被声明为protected.这意味着,它要么在一个实现了cloneable接口的类中的某一方法里被调用,要么在明确的在那个类中的被重写,且被声明为public的。下面,我们来看一下每一种方法。



The following program implements Cloneable and defines the 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 Object and returns the result. Notice that the object returned by clone( ) must be cast into its appropriate type (TestClone ). The following example overrides clone( ) so that it can be 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 to see at first. It is easy to think that a class is safe for cloning when it actually is not. In general, you should not implement Cloneable for any class without good reason.

 

以上两个程序,运行一下,便于理解。

 

以下在补充两点:

1  It is what is known as a 'marker' interface . A marker interface has no methods or fields and serves only to identify the semantics of that interface. Another example is Serializable .

2  object.clone()可能产生a shallow copy()也可能产生a deep copy.

 

参考:http://www.codeguru.com/forum/showthread.php?s=&postid=660398#post660398

 

 

5
0
分享到:
评论
3 楼 adam_zs 2013-03-26  
谢谢分享!
2 楼 adam_zs 2013-03-26  
谢谢分享。
1 楼 513282615 2011-07-14  

相关推荐

Global site tag (gtag.js) - Google Analytics