zoukankan      html  css  js  c++  java
  • Java浅拷贝与深拷贝(思维导图)

    图1 拷贝思维导图(点击查看图片)

    1,拷贝

      有两个相同属性的对象A和B,A拥有初始化值,将其值拷贝到B中,使得B拥有与A“相同”数据的属性!注意这里的相同我有加双引号!

      相同可能表示这么几个意思:①数值相同【指向不同的内存空间】;②地址相同【指向相同的内存空间】;

      下面是直接使用"="进行复制的操作

     1 package com.cnblogs.mufasa.Demo1;
     2 
     3 import java.util.Date;
     4 
     5 class Person{//
     6     private int age=0;
     7     private Birth birth=new Birth();
     8     private String name="";
     9 
    10     public Person(int age, Birth birth, String name) {
    11         this.age = age;
    12         this.birth = birth;
    13         this.name = name;
    14     }
    15 
    16     public int getAge() {
    17         return age;
    18     }
    19 
    20     public void setAge(int age) {
    21         this.age = age;
    22     }
    23 
    24     public Birth getBirth() {
    25         return birth;
    26     }
    27 
    28     public void setBirth(Birth birth) {
    29         this.birth = birth;
    30     }
    31 
    32     public String getName() {
    33         return name;
    34     }
    35 
    36     public void setName(String name) {
    37         this.name = name;
    38     }
    39     public String toString(){
    40         return "姓名:"+name+",年龄:"+age+",出生日期:"+birth.toString();
    41     }
    42 }
    43 
    44 class Birth{//生日
    45     private String date="";
    46     public Birth(){}
    47     public Birth(String date){
    48         this.date=date;
    49     }
    50 
    51     public String getDate() {
    52         return date;
    53     }
    54 
    55     public void setDate(String date) {
    56         this.date = date;
    57     }
    58 
    59     @Override
    60     public String toString() {
    61         return this.date;
    62     }
    63 }
    64 
    65 public class Demo1 {//浅拷贝
    66     public static void main(String[] args) {
    67         Person p1=new Person(18,new Birth("19950729"),"万雨");
    68         Person p2=p1;
    69         System.out.println(p1.toString());
    70         System.out.println(p2.toString());
    71 
    72         p1.setAge(17);
    73         p1.setBirth(new Birth("2018"));
    74         p1.setName("Mufasa");
    75 
    76         System.out.println(p1.toString());
    77         System.out.println(p2.toString());
    78 
    79     }
    80 }
    View Code
    姓名:万雨,年龄:18,出生日期:19950729
    姓名:万雨,年龄:18,出生日期:19950729
    姓名:Mufasa,年龄:17,出生日期:2018
    姓名:Mufasa,年龄:17,出生日期:2018

      其实就相当于对原始对象进行操作

    2,浅拷贝

      Perosn类型对象有两个属性Age、name,将p1浅复制给p2

      基本类型直接进行数值复制,引用类型进行地址拷贝(String类型比较特殊,属于引用类型,但是它存在一个常量池需要进行特殊对待)

     图2 浅拷贝

    使用构造方法进行浅拷贝:

     1 package com.cnblogs.mufasa.Demo;
     2 
     3 import java.util.Date;
     4 
     5 class Person{//
     6     private Age age;
     7     private String name;
     8     private int birth;
     9     public Person(Age age, String name,int birth) {
    10         this.age = age;
    11         this.name = name;
    12         this.birth = birth;
    13     }
    14 
    15     public Person(Person p1){
    16         this.age=p1.age;
    17         this.name=p1.name;
    18         this.birth=p1.birth;
    19     }
    20 
    21     public int getAge() {
    22         return this.age.getAge();
    23     }
    24 
    25     public void setAge(int age) {
    26         this.age.setAge(age); ;
    27     }
    28 
    29     public void setAge(Age age) {
    30         this.age = age;
    31     }
    32 
    33     public int getBirth() {
    34         return birth;
    35     }
    36 
    37     public void setBirth(int birth) {
    38         this.birth = birth;
    39     }
    40 
    41     public String getName() {
    42         return this.name;
    43     }
    44 
    45     public void setName(String name) {
    46         this.name = name;
    47     }
    48     public String toString(){
    49         return "姓名:"+this.name+",年龄:"+this.age+",出生日期:"+this.birth;
    50     }
    51 }
    52 
    53 class Age{
    54     private int age;
    55     public Age(){}
    56     public Age(int age){
    57         this.age=age;
    58     }
    59 
    60     public int getAge() {
    61         return age;
    62     }
    63 
    64     public void setAge(int age) {
    65         this.age = age;
    66     }
    67     public String toString(){
    68         return this.age+"";
    69     }
    70 }
    71 
    72 
    73 
    74 
    75 public class Demo {//浅拷贝-构造方法实现
    76     public static void main(String[] args) {
    77         Person p1=new Person(new Age(18),"万雨",1995);
    78         Person p2=new Person(p1);
    79         System.out.println(p1.toString());
    80         System.out.println(p2.toString());
    81 
    82         p1.setAge(17);
    83         p1.setBirth(2019);
    84         p1.setName("Mufasa");
    85 
    86         System.out.println(p1.toString());
    87         System.out.println(p2.toString());
    88 
    89     }
    90 }
    View Code

    使用继承Cloneable接口调用clone方法进行浅拷贝

      1 package com.cnblogs.mufasa.Demo2;
      2 
      3 import java.util.Date;
      4 
      5 class Person implements Cloneable{//
      6     private Age age;
      7     private String name;
      8     private int birth;
      9     public Person(Age age, String name,int birth) {
     10         this.age = age;
     11         this.name = name;
     12         this.birth = birth;
     13     }
     14 
     15     public Person clone(){
     16         Person obj=null;
     17         try {
     18             obj=(Person) super.clone();
     19         }catch (CloneNotSupportedException e){
     20             e.printStackTrace();
     21         }
     22 //        obj.age=(Age) this.getAge().clone();
     23         return obj;
     24     }
     25 
     26     public Age getAge() {
     27         return this.age;
     28     }
     29 
     30     public void setAge(int age) {
     31         this.age.setAge(age); ;
     32     }
     33 
     34     public void setAge(Age age) {
     35         this.age = age;
     36     }
     37 
     38     public int getBirth() {
     39         return birth;
     40     }
     41 
     42     public void setBirth(int birth) {
     43         this.birth = birth;
     44     }
     45 
     46     public String getName() {
     47         return this.name;
     48     }
     49 
     50     public void setName(String name) {
     51         this.name = name;
     52     }
     53     public String toString(){
     54         return "姓名:"+this.name+",年龄:"+this.age+",出生日期:"+this.birth;
     55     }
     56 }
     57 
     58 class Age implements Cloneable{
     59     private int age;
     60     public Age(){}
     61     public Age(int age){
     62         this.age=age;
     63     }
     64 //    public Age clone(){
     65 //        Age obj=null;
     66 //        try {
     67 //            obj=(Age) super.clone();
     68 //        }catch (CloneNotSupportedException e){
     69 //            e.printStackTrace();
     70 //        }
     71 //        return obj;
     72 //    }
     73 
     74     public int getAge() {
     75         return age;
     76     }
     77 
     78     public void setAge(int age) {
     79         this.age = age;
     80     }
     81     public String toString(){
     82         return this.age+"";
     83     }
     84 }
     85 
     86 
     87 
     88 
     89 public class Demo2 {//浅拷贝-继承Cloneable接口实现
     90     public static void main(String[] args) {
     91         Person p1=new Person(new Age(18),"万雨",1995);
     92         Person p2=(Person)p1.clone();
     93         System.out.println(p1.toString());
     94         System.out.println(p2.toString());
     95 
     96         p1.setAge(17);
     97         p1.setBirth(2019);
     98         p1.setName("Mufasa");
     99 
    100         System.out.println(p1.toString());
    101         System.out.println(p2.toString());
    102 
    103     }
    104 }
    View Code
    姓名:万雨,年龄:18,出生日期:1995
    姓名:万雨,年龄:18,出生日期:1995
    姓名:Mufasa,年龄:17,出生日期:2019
    姓名:万雨,年龄:17,出生日期:1995

    3,深拷贝

       引用类型数据也进行新内存开辟与幅值,

    图3 深拷贝

    使用继承Cloneable接口调用clone方法进行深拷贝【每个引用对象都需要使用clone方法进行拷贝】

      1 package com.cnblogs.mufasa.Demo2;
      2 
      3 import java.util.Date;
      4 
      5 class Person implements Cloneable{//
      6     private Age age;
      7     private String name;
      8     private int birth;
      9     public Person(Age age, String name,int birth) {
     10         this.age = age;
     11         this.name = name;
     12         this.birth = birth;
     13     }
     14 
     15     public Person clone(){
     16         Person obj=null;
     17         try {
     18             obj=(Person) super.clone();
     19         }catch (CloneNotSupportedException e){
     20             e.printStackTrace();
     21         }
     22         obj.age=(Age) this.getAge().clone();
     23         return obj;
     24     }
     25 
     26     public Age getAge() {
     27         return this.age;
     28     }
     29 
     30     public void setAge(int age) {
     31         this.age.setAge(age); ;
     32     }
     33 
     34     public void setAge(Age age) {
     35         this.age = age;
     36     }
     37 
     38     public int getBirth() {
     39         return birth;
     40     }
     41 
     42     public void setBirth(int birth) {
     43         this.birth = birth;
     44     }
     45 
     46     public String getName() {
     47         return this.name;
     48     }
     49 
     50     public void setName(String name) {
     51         this.name = name;
     52     }
     53     public String toString(){
     54         return "姓名:"+this.name+",年龄:"+this.age+",出生日期:"+this.birth;
     55     }
     56 }
     57 
     58 class Age implements Cloneable{
     59     private int age;
     60     public Age(){}
     61     public Age(int age){
     62         this.age=age;
     63     }
     64     public Age clone(){
     65         Age obj=null;
     66         try {
     67             obj=(Age) super.clone();
     68         }catch (CloneNotSupportedException e){
     69             e.printStackTrace();
     70         }
     71         return obj;
     72     }
     73 
     74     public int getAge() {
     75         return age;
     76     }
     77 
     78     public void setAge(int age) {
     79         this.age = age;
     80     }
     81     public String toString(){
     82         return this.age+"";
     83     }
     84 }
     85 
     86 
     87 
     88 
     89 public class Demo2 {//浅拷贝-继承Cloneable接口实现
     90     public static void main(String[] args) {
     91         Person p1=new Person(new Age(18),"万雨",1995);
     92         Person p2=(Person)p1.clone();
     93         System.out.println(p1.toString());
     94         System.out.println(p2.toString());
     95 
     96         p1.setAge(17);
     97         p1.setBirth(2019);
     98         p1.setName("Mufasa");
     99 
    100         System.out.println(p1.toString());
    101         System.out.println(p2.toString());
    102 
    103     }
    104 }
    View Code

     

    使用继承Serializable接口进行序列化与反序列化进行深拷贝【注意对象不能使用transient进行修饰,原因:transient修饰的对象无法进行序列化!】

     1 package com.cnblogs.mufasa.Demo3;
     2 
     3 
     4 import java.io.*;
     5 
     6 class Person implements Serializable{
     7     private Age age;
     8     private String name;
     9     private int birth;
    10     public Person(Age age, String name,int birth) {
    11         this.age = age;
    12         this.name = name;
    13         this.birth = birth;
    14     }
    15 
    16     public Age getAge() {
    17         return this.age;
    18     }
    19 
    20     public void setAge(int age) {
    21         this.age.setAge(age); ;
    22     }
    23 
    24     public void setAge(Age age) {
    25         this.age = age;
    26     }
    27 
    28     public int getBirth() {
    29         return birth;
    30     }
    31 
    32     public void setBirth(int birth) {
    33         this.birth = birth;
    34     }
    35 
    36     public String getName() {
    37         return this.name;
    38     }
    39 
    40     public void setName(String name) {
    41         this.name = name;
    42     }
    43     public String toString(){
    44         return "姓名:"+this.name+",年龄:"+this.age+",出生日期:"+this.birth;
    45     }
    46 }
    47 
    48 class Age implements Serializable {
    49     private int age;
    50     public Age(){}
    51     public Age(int age){
    52         this.age=age;
    53     }
    54     public int getAge() {
    55         return age;
    56     }
    57 
    58     public void setAge(int age) {
    59         this.age = age;
    60     }
    61     public String toString(){
    62         return this.age+"";
    63     }
    64 }
    65 
    66 
    67 
    68 
    69 public class Demo3 {//浅拷贝-继承Cloneable接口实现
    70     public static void main(String[] args) throws IOException, ClassNotFoundException {
    71         Person p1=new Person(new Age(18),"万雨",1995);
    72 
    73         ByteArrayOutputStream bos=new ByteArrayOutputStream();
    74         ObjectOutputStream oos=new ObjectOutputStream(bos);
    75 
    76         oos.writeObject(p1);//1,先进行序列化
    77         oos.flush();
    78         ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
    79         Person p2=(Person)ois.readObject();//2,进行反序列化
    80 
    81 
    82         System.out.println(p1.toString());
    83         System.out.println(p2.toString());
    84 
    85         p1.setAge(17);
    86         p1.setBirth(2019);
    87         p1.setName("Mufasa");
    88 
    89         System.out.println(p1.toString());
    90         System.out.println(p2.toString());
    91 
    92     }
    93 }
    View Code
    姓名:万雨,年龄:18,出生日期:1995
    姓名:万雨,年龄:18,出生日期:1995
    姓名:Mufasa,年龄:17,出生日期:2019
    姓名:万雨,年龄:18,出生日期:1995
  • 相关阅读:
    MyBatis配置文件(四)--typeHandlers
    MyBatis配置文件(三)--typeAliases别名
    理解JWT的使用场景和优劣
    JWT的使用流程
    JWT (JSON WEB Token)正确使用场景
    转 Spring Security 简介
    转 Solr vs. Elasticsearch谁是开源搜索引擎王者
    Oauth2.0(一):为什么需要 Oauth2.0 协议?
    Spring Security 与 OAuth2(介绍)
    理解OAuth 2.0
  • 原文地址:https://www.cnblogs.com/Mufasa/p/11378379.html
Copyright © 2011-2022 走看看