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. Ubuntu 17.10开启 root 登陆

    使用过 Ubuntu 的人都知道,Ubuntu 默认是不能以 root 登陆的,但是我们是不是就完全不能使用 root 进行登陆了呢?当然不是,只是我们需要做一些设置.而 Ubuntu 17.10 和 ...

  2. Chrome-Adobe Flash 无法正常使用

    https://support.google.com/chrome/answer/6258784 该网站因是是google.com,被强了,所以一般打不开. 故将google官方说明记录以下: 如果 ...

  3. MFC+WinPcap编写一个嗅探器之七(协议)

    这一节是本系列教程的结尾了,内容也比较简单,主要是对网络协议进行分析,其实学过计算机网络的同学完全可以略过 在整个项目中需要有一个头文件存放各层协议的头部定义,我把它们放在了head.h中,这个头文件 ...

  4. 【LOJ】#2537. 「PKUWC2018」Minimax

    题解 加法没写取模然后gg了QwQ,de了半天 思想还是比较自然的,线段树合并的维护方法我是真的很少写,然后没想到 很显然,我们有个很愉快的想法是,对于每个节点枚举它所有的叶子节点,对于一个叶子节点的 ...

  5. Android studio代码实现打电话+点击事件四种方式

    Android系统架构(重点) 第一层:应用层Application 第二层:应用框架层Application Framework 第三层:Android底层类库层 Libraries.Dalvik虚 ...

  6. C# 中从网络上下载文件保存到本地文件

    下面是C#中常用的从Internet上下载文件保存到本地的一些方法,没有太多的技巧. 1.通过  WebClient  类下载文件 WebClient webClient = new WebClien ...

  7. linux 添加samba账户

    1.adduser kilen   添加linux账户 2.cd /etc/samba/ 当前目录下修改smb.conf 文件 ,一般情况下是只读文件,需要修改权下 (用root用户) chmod 7 ...

  8. Python之路【第十一篇】: 进程与线程理论篇

    阅读目录 一 背景知识二 进程2.1 什么是进程2.2 进程与程序的区别2.3 并发与并行2.4 同步与异步2.5 进程的创建2.6 进程的终止2.7 进程的层次结构2.8 进程的状态2.9 进程并发 ...

  9. ASP.NET MVC 提高运行速度的几种性能优化方法

    主要介绍ASP.NETMVC 应用提速的六种方法,因为没有人喜欢等待,所以介绍几种常用的优化方法. 大家可能会遇到排队等待,遇到红灯要等待,开个网页要等待,等等等. 理所当然,没有人喜欢等待网页慢吞吞 ...

  10. [leetcode sort]57. Insert Interval

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...