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. C/C++经典面试题

    1.指向数组的指针 和 指向数组首元素的指针 2018-03-07 昨天在牛客上看到这么一道C语言面试题,挺经典的,特来分享给大家. 程序如下,问输出结果 #include <stdio.h&g ...

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

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

  3. ASP.NET:MVC中文件上传与地址变化处理

    目录 文件的上传和路径处理必须解决下面列出的实际问题: 1.重复文件处理 2.单独文件上传 3.编辑器中文件上传 4.处理文章中的图片路径 5.处理上传地址的变化 一.上传文件和重复文件处理 文件处理 ...

  4. 【51nod】1312 最大异或和

    题解 很显然我们求出一组线性基来,如果有M个基,那么可以构造N - M + 1个最大异或值 而对于线性基中的元素,除了最大的元素,我们用最大异或值异或掉每个元素累加进答案 而不是把线性基中的元素处理成 ...

  5. USACO 6.4 Wisconsin Squares

    Wisconsin Squares It's spring in Wisconsin and time to move the yearling calves to the yearling past ...

  6. 黑马程序员_java基础笔记(08)...GUI,网络编程,正则表达式

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— GUI(Graphical User Interface)(图形用户接口):用图形 ...

  7. PHP的exec()函数无返回值排查方法[转]

    在安全imagemagic时 需要用到 exec很多服务器上安装失败 exec()执行外部命令失败,但没有任何错误信息. exec执行某命令在命令行下没有问题,但是在PHP中就出错.这个问题99.99 ...

  8. 冒泡排序之Java实现

    冒泡排序之Java实现 一.方法一 package cn.com.zfc.lesson21.sort; import java.util.Arrays; /** * * @title BubbleSo ...

  9. luogu P3592 [POI2015]MYJ

    题目链接 luogu P3592 [POI2015]MYJ 题解 区间dp 设f[l][r][k]表示区间l到r内最小值>=k的最大收益 枚举为k的位置p,那么包含p的区间答案全部是k 设h[i ...

  10. BZOJ3207 花神的嘲讽计划

    hash值建主席树. 垃圾题面没有熟虑范围害我MLE——>RE. By:大奕哥 #include<bits/stdc++.h> #define unll unsigned long ...