1.终于调用的是一个JNI方法,即java本地方法,加高速度

2.使用clone方法,分为浅复制、深复制,这里直接使用网上抄来的案例来说明吧:

说明:

  1)为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在执行时刻,Object中的clone()识别你要复制的是哪一个对象,然后为此对象分配空间。并进行对象的复制,将原始对象的内容一一拷贝到新对象的存储空间中。

  2)继承自java.lang.Object.clone()方法是浅层复制。一下代码能够证明之:


 1 public class Student implements Cloneable {
2 private String name;
3 private int age;
4 private Professor pro;
5 public Student(){}
6 public Student(String name,int age,Professor pro){
7 this.name=name;
8 this.age=age;
9 this.pro=pro;
10 }
11 public Object clone(){
12 Object o=null;
13 try {
14 //Object中的clone()识别出你要复制的是哪一个对象。
15 o=super.clone();
16 } catch (CloneNotSupportedException e) {
17 System.out.println(e.toString());
18 }
19 return o;
20 }
21 public String getName() {
22 return name;
23 }
24 public void setName(String name) {
25 this.name = name;
26 }
27 public int getAge() {
28 return age;
29 }
30 public void setAge(int age) {
31 this.age = age;
32 }
33 public Professor getPro() {
34 return pro;
35 }
36 public void setPro(Professor pro) {
37 this.pro = pro;
38 }
39 }
40 class Professor{
41 private String name;
42 private int age;
43 public Professor(){}
44 public Professor(String name,int age){
45 this.name=name;
46 this.age=age;
47 }
48 public String getName() {
49 return name;
50 }
51 public void setName(String name) {
52 this.name = name;
53 }
54 public int getAge() {
55 return age;
56 }
57 public void setAge(int age) {
58 this.age = age;
59 }
60 }

 1 public class StudentTest {
2 public static void main(String[] args) {
3 Professor p=new Professor("wangwu",50);
4 Student s1=new Student("zhangsan",18,p);
5 Student s2=(Student)s1.clone();
6 s2.getPro().setName("maer");
7 s2.getPro().setAge(40);
8 System.out.println("name="+s1.getPro().getName()
9 +",age="+s1.getPro().getAge());
10 //name=maer,age=40
11 }
12 }

  那么我们怎样实现深层复制的克隆,即在改动s2.Professor时不影响s1.Professor?代码改进例如以下:


 1 public class Student implements Cloneable {
2 private String name;
3 private int age;
4 Professor pro;
5 public Student(){}
6 public Student(String name,int age,Professor pro){
7 this.name=name;
8 this.age=age;
9 this.pro=pro;
10 }
11 public Object clone(){
12 Student o=null;
13 try {
14 //Object中的clone()识别出你要复制的是哪一个对象。 15 o=(Student)super.clone();
16 } catch (CloneNotSupportedException e) {
17 System.out.println(e.toString());
18 }
19 o.pro=(Professor)pro.clone();
20 return o;
21 }
22 public String getName() {
23 return name;
24 }
25 public void setName(String name) {
26 this.name = name;
27 }
28 public int getAge() {
29 return age;
30 }
31 public void setAge(int age) {
32 this.age = age;
33 }
34 public Professor getPro() {
35 return pro;
36 }
37 public void setPro(Professor pro) {
38 this.pro = pro;
39 }
40 }
41 class Professor implements Cloneable{
42 private String name;
43 private int age;
44 public Professor(){}
45 public Professor(String name,int age){
46 this.name=name;
47 this.age=age;
48 }
49 public Object clone(){
50 Object o=null;
51 try {
52 o=super.clone();
53 } catch (CloneNotSupportedException e) {
54 e.printStackTrace();
55 }
56 return o;
57 }
58 public String getName() {
59 return name;
60 }
61 public void setName(String name) {
62 this.name = name;
63 }
64 public int getAge() {
65 return age;
66 }
67 public void setAge(int age) {
68 this.age = age;
69 }
70 }
public class StudentTest {
public static void main(String[] args) {
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.clone();
s2.getPro().setName("maer");
s2.getPro().setAge(40);
System.out.println("name="+s1.getPro().getName()
+",age="+s1.getPro().getAge());
//name=wangwu,age=50
}
}

也就是说浅复制仅仅复制了一些主要的属性,可是里面的引用的属性并没有真正的复制,所以假设想要达到深复制,还要在复写的代码中进行处理。将全部引用的对象也都调用它们的clone()方法。

下面是摘抄的网友的三点小总结:

clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:

①对不论什么的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象

②对不论什么的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样

③假设对象x的equals()方法定义恰当。那么x.clone().equals(x)应该成立。

以下重点说一下,为什么String相同是对象。可是却不用特殊处理;理由例如以下:

String不是基本数据类型。可是在深复制的时候并没有进行单独的复制。也就是说违反了深复制,只复制了引用,而String没有实现cloneable接口,也就是说只能复制引用。

那么在改动克隆之后的对象之后,会不会将原来的值也改变了?

答案肯定是不会改变,由于String是在内存中不能够被改变的对象,就比方说在for大量循环中不推荐使用+的方式来拼凑字符串一样,每次使用+都会新分配一块内存,不在原来上改动,原来的没有指向它的引用,会被回收。所以克隆相当于1个String内存空间有两个引用,当改动当中的一个值的时候。会新分配一块内存用来保存新的值,这个引用指向新的内存空间,原来的String由于还存在指向他的引用,所以不会被回收,这样,尽管是复制的引用,可是改动值的时候,并没有改变被复制对象的值。

所以在非常多情况下。我们能够把String在clone的时候和基本类型做同样的处理。仅仅是在equal时注意一些即可了。

Java clone方法(下)的更多相关文章

  1. Java clone() 方法克隆对象——深拷贝与浅拷贝

    基本数据类型引用数据类型特点 1.基本数据类型的特点:直接存储在栈(stack)中的数据 2.引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指 ...

  2. Java clone方法的使用

    浅克隆 Person p2 = (Person) p1.clone(); clone()方法使用后得到p2,p2和p1指向不同的地址.但是如果p1中的属性是引用类型,那么不再对这个引用类型进行复制,而 ...

  3. 详解Java中的clone方法:原型模式

    转:http://developer.51cto.com/art/201506/478985.htm clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的 ...

  4. Effective Java 第三版——13. 谨慎地重写 clone 方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  5. Java 的 clone 方法 && 浅复制和深复制

    1 Java中对象的创建过程 java创建对象的方式有以下两种: (1)使用new操作符创建一个对象 (2)使用clone的方法复制一个对象,(在Java中,clone是Object类的protect ...

  6. java Object对象的clone方法

    参考copy链接:http://blog.csdn.net/bigconvience/article/details/25025561 在看原型模式,发现要用到clone这个方法,以前和朋友聊过,没怎 ...

  7. 详解Java中的clone方法 -- 原型模式

    转自: http://blog.csdn.net/zhangjg_blog/article/details/18369201 Java中对象的创建   clone顾名思义就是复制, 在Java语言中, ...

  8. java中的clone方法

    Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...

  9. 深入浅出| java中的clone方法

    每天进步一丢丢,连接梦与想 我们还年轻,但这不是你浪费青春的理由 克隆和复制 clone,有人称之为克隆,有人称之为复制,其实都是同一个东西 本文称之为"克隆",毕竟人家方法名叫& ...

随机推荐

  1. 20155309南皓芯 实验2 Windows口令破解

    在网络界,攻击事件发生的频率越来越高,其中相当多的都是由于网站密码泄露的缘故,或是人为因素导致,或是口令遭到破解,所以从某种角度而言,密码的安全问题不仅仅是技术上的问题,更主要的是人的安全意识问题. ...

  2. 在Eclipse中导入新浪微博SDK

    在Eclipse中导入新浪微博SDK 今天在看<Android开发应用实战>,全书都在讲一个android版的新浪微博客户端怎么做,于是按照书上步骤做.网上有人说这本书没有细节,我想对于小 ...

  3. 洛谷 P1992 不想兜圈的老爷爷 题解

    洛谷 P1992 不想兜圈的老爷爷 题解 题目描述 一位年过古稀的老爷爷在乡间行走 而他不想兜圈子 因为那会使他昏沉 偶然路过小A发扬助人为乐优良传统 带上地图 想知道路况是否一定使他清醒 usqwe ...

  4. LoadRunner FAQ

    LoadRunner FAQ web_concurrent_start和web_concurrent_end web_concurrent_start 语法: int web_concurrent_s ...

  5. Dubbo中只订阅与只注册

    一:只订阅 1.场景 为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行. 可以让服务提供者开发方,只订阅服务(开发的服 ...

  6. C#导出HTML到PDF组件Pechkin

    http://www.knowsky.com/898441.html C#导出PDF功能是开发中经常遇到的功能,我们采用第三方的组件,比如 iTextSharp, aspose等,还能搜到一些开源的类 ...

  7. 通过GeneXus如何快速构建微服务架构

    概览 “微服务”是一个非常广泛的话题,在过去几年里,市面上存在着各种不同的定义. 虽然对这种架构方式没有一个非常精确的定义,但仍然有一些概念具有代表性. 微服务有着许多围绕业务能力.自动化部署.终端智 ...

  8. Java_正则表达式&时间日期

    正则表达式 1.概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符合某个句法规则 ...

  9. Initramfs 原理和实践

    Linux系统启动时使用initramfs (initram file system), initramfs可以在启动早期提供一个用户态环境,借助它可以完成一些内核在启动阶段不易完成的工作.当然ini ...

  10. Vue图片懒加载插件

    图片懒加载是一个很常用的功能,特别是一些电商平台,这对性能优化至关重要.今天就用vue来实现一个图片懒加载的插件. 这篇博客采用"三步走"战略--Vue.use().Vue.dir ...