zoukankan      html  css  js  c++  java
  • (原)java中对象复制、==、equals

    对于基本数据类型而言,即如下八种基本数据类型,int,boolean,char,byte,short,float,double,long。

     1 public class test
     2 {
     3     public static void main(String[] args)
     4     {
     5         int a=3;
     6         int b=a;
     7         int c=3;
     8         b=2;
     9         System.out.println("a:    "+a);
    10         System.out.println("b:    "+b);
    11         System.out.println(a==b);
    12         System.out.println(a==c);
    13         
    14     }
    15 }

    说明:对于基本数据类型,==只是比较两个变量的值,并没有比较其地址,并且其变量复制后,任意改变其中一个变量时,并没有对另一个变量产生变化,默认实现的是深拷贝。

    一个简单的浅拷贝示例,浅拷贝中复制出来的对象的域与原始对象的域使用相同的对象引用,指向的是同一个对象,相当于在两个对象中对同一个对象进行处理,会产生潜在的问题。

    Object类的clone方法复制对象的做法是对当前对象中所有实例域进行逐一复制。先创建一个新的对象,再把新对象中所有的实例域的值初始化成原始对象中对应域的当前值。

    
    
     1 class ToBeCloned implements Cloneable//Cloneable为标记接口,其内不包含任何方法,要实现此接口的话,必须重写clone方法,否则
     2 //抛出异常java.lang.CloneNotSupportedException异常
     3 {
     4 private int value=0;
     5 public void setValue(int value)
     6 {
     7 this.value=value;
     8 }
     9 public int getValue()
    10 {
    11 return this.value;
    12 }
    13 public Object clone()
    14 {
    15 try
    16 {
    17 return super.clone();
    18 }
    19 catch(CloneNotSupportedException e)
    20 {
    21 throw new Error(e);
    22 }    
    23 }
    24 }
    25 
    26 
    27 public class SimpleClone
    28 {
    29 public static void main(String[] args)
    30 {
    31 ToBeCloned obj=new ToBeCloned();
    32 obj.setValue(1);
    33 ToBeCloned cloneObj=(ToBeCloned)obj.clone();
    34 
    35 System.out.println("cloneObj.getValue():    "+cloneObj.getValue());
    36 System.out.println("obj.getValue():    "+obj.getValue());
    37 obj.setValue(2);
    38 System.out.println("cloneObj.getValue():    "+cloneObj.getValue());
    39 System.out.println("obj.getValue():    "+obj.getValue());
    40 }
    41 }

    
    

     如果对象中只包含值为基本类型或不可变对象的域,用上面的方法就可以了,内部域为基本数据类型。但是当对象中某些域的值为可变对象时,上述方法就不能满足了。示例如下:

     1 class Counter
     2 {
     3     private int value=0;
     4     public void increase()
     5     {
     6         value++;
     7     }
     8     public int getValue()
     9     {
    10         return value;
    11     }
    12 }
    13 
    14 class MutableObject implements Cloneable
    15 {
    16     private Counter counter=new Counter();
    17     public void increase()
    18     {
    19         counter.increase();
    20     }
    21     public  int getValue()
    22     {
    23         return counter.getValue();
    24     }
    25     public Object clone()
    26     {
    27         try 
    28         {
    29             return super.clone();
    30         }
    31         catch(CloneNotSupportedException e)
    32         {
    33             throw new Error(e);
    34         }
    35     }
    36 }
    37 
    38 
    39 public class MutableObjectClone
    40 {
    41     public static void main(String[] args)
    42     {
    43         MutableObject obj=new  MutableObject();
    44         obj.increase();
    45         MutableObject clonedObj=(MutableObject)obj.clone();
    46         clonedObj.increase();
    47         obj.increase();
    48         System.out.println(clonedObj.getValue());
    49         System.out.println(obj.getValue());
    50     }
    51 }

    这说明Object类的clone方法已经对类中的基本类型和不可变对象的域进行了处理,只要在这基础上添加对可变对象的域的处理即可。即通过递归的方式来对clone进行修改。

    因为在Counter中value为int类型,故递归截止为此函数。

     1 class Counter implements Cloneable
     2 {
     3     private int value=0;
     4     public void increase()
     5     {
     6         value++;
     7     }
     8     public int getValue()
     9     {
    10         return value;
    11     }
    12     public Object clone()
    13     {
    14         try
    15         {
    16             return super.clone();
    17         }
    18         catch(CloneNotSupportedException e)
    19         {
    20             throw new Error(e);
    21         }
    22     }
    23 }
    24 
    25 class MutableObject implements Cloneable
    26 {
    27     private Counter counter=new Counter();
    28     public void increase()
    29     {
    30         counter.increase();
    31     }
    32     public  int getValue()
    33     {
    34         return counter.getValue();
    35     }
    36     public Object clone()
    37     {
    38         MutableObject obj;
    39         try 
    40         {
    41             obj=(MutableObject)super.clone();
    42             obj.counter=(Counter)counter.clone();
    43             return obj;
    44         }
    45         catch(CloneNotSupportedException e)
    46         {
    47             throw new Error(e);
    48         }
    49     }
    50 }
    51 
    52 
    53 public class MutableObjectClone
    54 {
    55     public static void main(String[] args)
    56     {
    57         MutableObject obj=new  MutableObject();
    58         obj.increase();
    59         MutableObject clonedObj=(MutableObject)obj.clone();
    60         clonedObj.increase();
    61         obj.increase();
    62         obj.increase();
    63         System.out.println("clonedObj.getValue():    "+clonedObj.getValue());
    64         System.out.println("obj.getValue():        "+obj.getValue());
    65     }
    66 }

    在这里要注意在类Object中,clone()方法是protected权限的。

    进行复制对象的另外一个做法是使用复制构造方法,即用一个已有 的对象去构造另外一个对象。

    示例如下:

     1 public class UserException
     2 {
     3     private String name;
     4     private String email;
     5 
     6     public User(String name,String email)
     7     {
     8         this.name=name;
     9         this.email=email;
    10     }     
    11     public User(User user)
    12     {
    13         this.name=user.getName();
    14         this.email=user.getEmail();    
    15     }
    16     
    17     public String getName()
    18     {
    19         return this.name;
    20     }
    21     public String getEmail()
    22     {
    23         return this.email;
    24     }
    25 }
  • 相关阅读:
    小实例 hangman game
    二分搜索
    基于xml的aop开发
    Discuz! 6.x/7.x 全局变量防御绕过导致命令执行
    PHP执行linux系统命令
    IP反查网站,ip反查接口,旁站查询接口大全,通过IP查域名汇总:
    取消sudo的密码
    linux之kali系统ssh服务开启
    Linux下自动备份MySQL数据库详细操作步骤(转载)
    MongoDB学习笔记(一) MongoDB介绍及安装
  • 原文地址:https://www.cnblogs.com/xh0102/p/5683624.html
Copyright © 2011-2022 走看看