`
Sunshyfangtian
  • 浏览: 246389 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类
最新评论

Cloneable 接口

    博客分类:
  • Java
阅读更多

Cloneable 接口

 

·public interface Cloneable此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。

 

如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException  异常。

 

按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的)。请参阅 Object.clone(),以获得有关重写此方法的详细信息。

 

注意,此接口不 包含 clone 方法。因此,因为某个对象实现了此接口就克隆它是不可能的。即使 clone 方法是反射性调用的,也无法保证它将获得成功。

 

 

·cloneable接口是一个标志性的接口,实现他可以不实现任何方法。使用了它就标志这个类可以复制,如果想实现深层次的克隆,那就要重载clone()方法。

 

·若需要修改一个对象,同时不想改变调用者的对象,就用克隆,  
    先用implements   Cloneble实现Cloneble接口,  
    再实现clone();

 

 

·这是里面的一段(非完整的例子):  
  public   class   Snake   implements   Cloneable   {  
   
  ...........................  
   
  public   Object   clone()   {  
          Object   o   =   null;  
          try   {  
              o   =   super.clone();  
          }   catch   (CloneNotSupportedException   e)   {}  
          return   o;

 

 

·copy书上一段给你看看,希望有帮助把。。  
  当制作实例变量的一个引用时,原始实例变量和副本实力变量在内存中引用的均是同一个存储空间,这就意味着但对其中一个实例变量操作时就会影响到这个对象的副本。例如下面的程序代码。在执行时将会看到所画的两条线重合在一起,都是改变后的LineFigure1。  
  LineFigure   lineFigure1   =   new   LineFigure();  
  LineFigure   lineFigure2   =   lineFigure1;  
  lineFigure1.draw(g);  
  …code   for   changing   lineFigure1  
  lineFigure2.draw(g);  
  如果想让LineFigure2成为一个新的对象,就要用到Clone(   )方法。Clone的后对象和原对象的存储空间不同,改变其中一个并不会对另一个产生任何影响。例如下面代码所示:  
  …………….  
  LineFigure2   =   lineFigure1.clone();  
  …………….  
  如果LineFigure2中没有对其他对象的引用,事情就到此结束了,但LineFigure类中的实例变量StartPoint和EndPoint都是一个对象,即使简单地实现了对LineFigure1地Clone,可LineFigure1和LineFigure2的StartPoint和EndPoint实例变量引用的是同一个变量,要想完全的实现将LineFigure2和LineFigure1分离开,就要实现Cloneable接口,并重写Clone方法。Cloneable接口是Java提供的少数几个标签化接口之一。平常所说的标签化接口就是不提供任何方法的接口。在图形白板程序中,也用到了Cloneable接口,例如LineFigure类中的代码:  
  public   class   LineFigure   extends   Figure   implements   Cloneable{  
      public   Object   clone(){  
          LineFigure   lineFigure   =   new   LineFigure();  
          lineFigure.startPoint   =   (Point)startPoint.clone();  
          lineFigure.endPoint   =   (Point)endPoint.clone();  
          lineFigure.firstDraw   =   firstDraw;  
          return   lineFigure;  
      }  
  ………………..  
  }  
  这样一来,LineFigure1和LineFigure2所引用的对象就没有任何的重合。对其中任何一个进行修改而不影响另一个的应用。  

 

 

 

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

 

......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.

 

 

分享到:
评论

相关推荐

    Java实验7抽象类和接口.pdf

    抽象类和接口 ...通过这个实验,我们学习了抽象类、接口、Cloneable 接口和多态性的概念,并掌握了如何使用它们来编写 Java 程序。我们还学习了浅拷贝和深拷贝的概念,并掌握了如何消除浅拷贝的方法。

    学习Java实验7抽象类和接口.pdf

    本实验主要讲解了Java中的抽象类和接口的概念和使用方法,并且深入探讨了 Cloneable 接口和 clone 方法在对象内容复制中的应用。 一、抽象类的概念和使用方法 在 Java 中,抽象类是一个不能被实例化的类,它提供了...

    day16-Map、可变参数、Cloneable.pdf

    总的来说,Map接口提供了一种高效的方式来存储和检索键值对数据,可变参数简化了函数调用,Cloneable接口支持对象的克隆,而多线程则为并发编程提供了基础。理解和掌握这些知识点对于Java开发至关重要。

    编程语言java对象复制.pdf

    在给出的内容部分中,通过具体的Java代码示例,讨论了在Java中实现对象复制的机制,特别是通过实现Cloneable接口和重写Object类的clone方法来完成对象的浅复制与深复制。 知识点一:Java对象复制的基本概念 在Java...

    Java语言程序设计ppt第十四章(抽象类和接口)

    Cloneable 接口是一个接口,它只有一个抽象方法 `clone`,这个方法用于创建对象的副本。Cloneable 接口可以被多个类实现,每个类可以实现多个接口。例如,String 类实现了 Cloneable 接口,以便创建字符串的副本。 ...

    2型模式-MOOC课程内容.pdf

    所有类都继承自Object类,因此所有Java类都可以调用clone()方法,但前提是类必须实现Cloneable接口,否则会抛出CloneNotSupportedException异常。 克隆方法(clone方法)在使用时有以下限制: 1. clone方法总是返回...

    clone 深度克隆对象

    前者需要特别注意的是,只有实现了Cloneable接口的类才能调用默认的clone()方法,否则会抛出CloneNotSupportedException异常。此外,如果对象内部包含不可克隆的对象(如final类型的对象或没有实现Cloneable接口的...

    ava常用设计模式-原型模式

    Cloneable 接口是一个标记接口,用于标识类可以被克隆。在 Java 中,Object 类提供了 clone() 方法,该方法用于创建对象的副本。然而,Object 类的 clone() 方法是 protected 的,因此需要在子类中重写该方法以便...

    Java原型模式

    在Java中,原型模式通过实现Cloneable接口和覆盖clone()方法来复制对象,避免了使用构造函数进行深度复制的复杂性。接下来我们将深入探讨Java原型模式的核心概念、实现方式以及实际应用。 ### 核心概念 1. **原型...

    2022年抽象类和接口2.ppt

    在Java编程语言中,抽象类和接口是两种...同时,`Calendar` 类和 `GregorianCalendar` 类,以及 `Comparable`、`Cloneable` 接口等,都是在实际开发中经常遇到的工具,理解并熟练运用它们可以提高代码的效率和质量。

    Java实验3Java实验3.doc

    Java 实验 3 继承和多态 一、实验目的: 1. 学习和使用类的继承 ...本实验旨在学习和掌握 Java 语言的继承、多态、抽象类、接口、Cloneable 接口和对象内容的复制等概念和技术,並通過實踐掌握这些技术的应用。

    原型模式代码示例

    1. **实现Cloneable接口**:首先,我们需要让我们的类实现`Cloneable`接口。这个接口不包含任何方法,但它标志着一个类可以被克隆。当我们尝试对一个对象调用`clone()`方法而该对象所属的类没有实现`Cloneable`接口...

    gson深度克隆jar包

    Gson深度克隆是一个利用Gson库实现对象深度克隆的工具,主要通过将对象序列化为JSON字符串,再从JSON字符串反...易用性:无需实现Cloneable接口,适合快速开发。 性能考虑:适用于小到中等规模对象,性能开销相对较低。

    JAVA抽象类和接口讲义PPT教案学习.pptx

    6. **Cloneable接口**: - 实现`Cloneable`接口的对象可以通过`clone()`方法进行浅复制。 7. **包装类与基本类型之间的自动转换**: - Java提供了对应的包装类(如`Integer`、`Double`等)用于封装基本类型,并且...

    Java中的深拷贝(深复制)和浅拷贝(浅复制) 示例代码

    深拷贝可以通过序列化和反序列化实现,或者手动实现Cloneable接口并重写`clone()`方法。 示例代码(使用序列化): ```java import java.io.*; class MyClass implements Serializable { int a; String b; ...

    通过java实现原型模式(Prototype Pattern).rar

    Java中有一个内置的Cloneable接口和Object类的clone()方法,它们可以被用来实现对象的克隆。但是,直接使用clone()方法需要处理一些复杂的问题,比如深拷贝和浅拷贝的区别。 压缩包文件代码是一个使用Java实现原型...

    原型模式类

    在Java等支持克隆操作的语言中,原型模式可以通过实现Cloneable接口来实现。`Cloneable`接口表明一个对象可以被复制。当一个类实现了这个接口,那么就可以调用其`clone()`方法来创建一个与原对象相同的新对象。但是...

    [创建型模式] 原型模式的理解

    在Java等编程语言中,原型模式通过实现Cloneable接口来实现对象的复制。Cloneable接口没有定义任何方法,但它的存在表明该类的对象可以被克隆。当试图克隆一个实现了Cloneable接口的对象时,系统会调用默认的克隆...

    通过C++实现原型模式(Prototype Pattern).rar

    由于C++没有内置的克隆机制像Java的Cloneable接口那样,因此我们需要手动实现克隆逻辑。 压缩包文件代码是一个使用C++实现原型模式的简单例子。 注意事项 1、在C++中,我们通常使用智能指针(如std::unique_ptr或std...

Global site tag (gtag.js) - Google Analytics