今天看了一上午关于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.

java cloneable 用途_java中的clon()和cloneable接口浅析(转)相关推荐

  1. java画板抽象类_java 中的 抽象方法 抽象类 和 接口有啥瓜葛

    文章目录 什么是java中的抽象方法 抽象方法是一种特殊的方法: 它只有声明,而没有具体的实现 例如: abstract void eat(); 上面定义了一个方法 eat() ,有修饰关键词 abs ...

  2. java cloneable 用途_java中cloneable的使用

    什么是java中的浅克隆和深克隆? 浅克隆:克隆对象中的变量与之前对象的值相同,并且对象中的引用类型变量仍然指向原来对象引用类型变量的地址. 深克隆:克隆对象中的变量与之前对象的值相同,并且对象中的引 ...

  3. java.util接口_Java 8中java.util.function包中的谓词和使用者接口

    java.util接口 在上一篇文章中,我写了关于Function接口的内容 ,它是java.util.package的一部分. 我还提到了Predicate接口,它是同一包的一部分,在这篇文章中,我 ...

  4. Java 8中java.util.function包中的谓词和使用者接口

    在我以前的文章中,我写了关于Function接口的内容 ,它是java.util.package的一部分. 我还提到了Predicate接口,它是同一包的一部分,在这篇文章中,我将向您展示如何使用Pr ...

  5. java 序列化实例_Java中的序列化与反序列化实例

    创建的字节流与平台无关.因此,在一个平台上序列化的对象可以在另一个平台上反序列化. 为了使Java对象可序列化,我们实现java.io.Serializable可序列化接口. ObjectOutput ...

  6. java outer关键字_java中的关键字

    abstract : 表明类或者成员方法具有抽象属性 assert : 断言,用来进行程序调试 boolean :基本数据类型之一,声明布尔类型的关键字 break :提前跳出一个块 byte :基本 ...

  7. java final 函数_JAVA中Final的用法

    1.         修饰基础数据成员的final 这是final的主要用途,其含义相当于C/C++的const,即该成员被修饰为常量,意味着不可修改.如java.lang.Math类中的PI和E是f ...

  8. java集合总结_Java中集合总结

    Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合,这些集合类都位于java.util包中,但是与数组不同的是,集合中不能存放基本类型数据,而 ...

  9. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

最新文章

  1. 陈天桥雒芊芊脑机接口中心等团队研究登顶刊:超声波“读心”
  2. matlab神经网络3:模式分类
  3. MySQL日期及时间加减函数
  4. 零点追踪(零点及量程补偿)
  5. ubuntu两个conda安装和切换
  6. 单目相机内参标定的问题
  7. cognos安装和配置即席报表流程
  8. 流过的时光... 想到了曾经的我某个情节我笑了...
  9. linux rzsz安装
  10. 开普勒行星运动三定律
  11. 路由器自动重启指令_如何按计划自动重启路由器,简便方法
  12. 7-15 新浪微博热门话题
  13. VBox 启动虚拟机失败 - NtCreateFile(\Device\VBoxDrvStub)
  14. ffmepg H264 NALU分析
  15. 使用蓝桥杯单片机实现ADC采集和实时时钟界面转换与报警功能
  16. 第八部份:Bless安装
  17. linux下添加网口,linux下ioctl操作网络接口
  18. css玻璃雨滴效果,CSS实现雨滴动画效果的实例代码
  19. 阿里巴巴首面之面试题
  20. Linux 设备驱动那些事

热门文章

  1. h3c linux驱动 wn612_H3C iNode智能客户端安装指导(Linux)-7.3-5PW102
  2. 使用《红孩儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏
  3. spring启动加载机制spring.factories使用方法
  4. python-Beautiful rose
  5. C#设计模式系列 9 ----Facade外观模式之--天河城购物
  6. 农行K宝无法使用,设备管理器显示叹号
  7. 2020 AI 算法工程师常见知识点整合
  8. 电路与电子1.4实际电容与电源滤波
  9. 【BZOJ3930】【CQOI2015】选数
  10. java汽车油耗计算_转发一个手机油耗计算器 (java)