Cloneable 接口

2024-02-21 05:08
文章标签 接口 cloneable

本文主要是介绍Cloneable 接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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.

 

 

这篇关于Cloneable 接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/730653

相关文章

requests处理token鉴权接口和jsonpath使用方式

《requests处理token鉴权接口和jsonpath使用方式》文章介绍了如何使用requests库进行token鉴权接口的处理,包括登录提取token并保存,还详述了如何使用jsonpath表达... 目录requests处理token鉴权接口和jsonpath使用json数据提取工具总结reques

python调用dubbo接口的实现步骤

《python调用dubbo接口的实现步骤》本文主要介绍了python调用dubbo接口的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录 ​​其他实现方式与注意事项​​ ​​高级技巧与集成​​用 python 提供 Dubbo 接口

Java中接口和抽象类的异同以及具体的使用场景

《Java中接口和抽象类的异同以及具体的使用场景》文章主要介绍了Java中接口(Interface)和抽象类(AbstractClass)的区别和联系,包括相同点和不同点,以及它们在实际开发中的具体使... 目录一、接口和抽象类的 “相同点”二、接口和抽象类的 “核心区别”关键区别详解(避免踩坑)三、具体使

MySQL中C接口的实现

《MySQL中C接口的实现》本节内容介绍使用C/C++访问数据库,包括对数据库的增删查改操作,主要是学习一些接口的调用,具有一定的参考价值,感兴趣的可以了解一下... 目录准备mysql库使用mysql库编译文件官方API文档对象的创建和关闭链接数据库下达sql指令select语句前言:本节内容介绍使用C/

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

基于Redisson实现分布式系统下的接口限流

《基于Redisson实现分布式系统下的接口限流》在高并发场景下,接口限流是保障系统稳定性的重要手段,本文将介绍利用Redisson结合Redis实现分布式环境下的接口限流,具有一定的参考价值,感兴趣... 目录分布式限流的核心挑战基于 Redisson 的分布式限流设计思路实现步骤引入依赖定义限流注解实现

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例