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. hdu 1007 N个点中输出2点的最小距离的一半

    分治法 Sample Input20 01 121 11 13-1.5 00 00 1.50 Sample Output0.710.000.75 # include <iostream> ...

  2. python 判断字符编码

    一般情况下,需要加这个: import sys reload(sys) sys.setdefaultencoding('utf-8') 打开其他文件编码用codecs.open 读 下面的代码读取了文 ...

  3. centos7 关闭默认firewalld,开启iptables

    编者按: 对于使用了centos6系列系统N年的运维来说,在使用centos7的时候难免会遇到各种不适应.比如防火墙问题.本文主要记录怎么关闭默认的firewalld防火墙,重新启用iptables. ...

  4. 实现nlp文本生成中的beam search解码器

    自然语言处理任务,比如caption generation(图片描述文本生成).机器翻译中,都需要进行词或者字符序列的生成.常见于seq2seq模型或者RNNLM模型中. 这篇博文主要介绍文本生成解码 ...

  5. Mac下思维导图Xmind使用入门

    1.软件下载 中文官网地址: http://www.xmindchina.net   安装过程比较傻瓜化,这里就不截图了. 2.用Xmind设计软件模块: 1>.新建一个思维导图,如下图,选 ...

  6. 【记录】【持续更新】mybatis使用记录

    1.>  < 等符号在mybatis中的sql语句需要转义 > : > < : < 2.mybatis动态选择 <choose> <when te ...

  7. 基于五阶段流水线的RISC-V CPU模拟器实现

    RISC-V是源自Berkeley的开源体系结构和指令集标准.这个模拟器实现的是RISC-V Specification 2.2中所规定RV64I指令集,基于标准的五阶段流水线,并且实现了分支预测模块 ...

  8. React Native踩坑之FlatList组件中的onEndReached

    最近在做一个RN项目,有使用到FlatList这样一个RN封装的组件去做上拉加载更多功能,在iOS和Android平台上,总结了以下几个遇到的问题及解决方案 1. 进入页面onReached开始就被触 ...

  9. 传递 hdu 5961 拓扑排序有无环~

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5961 题目为中文,这里就不描述题意了. 思路: 从题目陈述来看,他将一个有向图用一个邻接矩阵来表示,并且分 ...

  10. 【CF 585E】 E. Present for Vitalik the Philatelist

    E. Present for Vitalik the Philatelist time limit per test 5 seconds memory limit per test 256 megab ...