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

 public class test
{
public static void main(String[] args)
{
int a=3;
int b=a;
int c=3;
b=2;
System.out.println("a: "+a);
System.out.println("b: "+b);
System.out.println(a==b);
System.out.println(a==c); }
}

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

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

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


 class ToBeCloned implements Cloneable//Cloneable为标记接口,其内不包含任何方法,要实现此接口的话,必须重写clone方法,否则
//抛出异常java.lang.CloneNotSupportedException异常
{
private int value=0;
public void setValue(int value)
{
this.value=value;
}
public int getValue()
{
return this.value;
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class SimpleClone
{
public static void main(String[] args)
{
ToBeCloned obj=new ToBeCloned();
obj.setValue(1);
ToBeCloned cloneObj=(ToBeCloned)obj.clone(); System.out.println("cloneObj.getValue(): "+cloneObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
obj.setValue(2);
System.out.println("cloneObj.getValue(): "+cloneObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
}
}


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

 class Counter
{
private int value=0;
public void increase()
{
value++;
}
public int getValue()
{
return value;
}
} class MutableObject implements Cloneable
{
private Counter counter=new Counter();
public void increase()
{
counter.increase();
}
public int getValue()
{
return counter.getValue();
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class MutableObjectClone
{
public static void main(String[] args)
{
MutableObject obj=new MutableObject();
obj.increase();
MutableObject clonedObj=(MutableObject)obj.clone();
clonedObj.increase();
obj.increase();
System.out.println(clonedObj.getValue());
System.out.println(obj.getValue());
}
}

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

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

 class Counter implements Cloneable
{
private int value=0;
public void increase()
{
value++;
}
public int getValue()
{
return value;
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} class MutableObject implements Cloneable
{
private Counter counter=new Counter();
public void increase()
{
counter.increase();
}
public int getValue()
{
return counter.getValue();
}
public Object clone()
{
MutableObject obj;
try
{
obj=(MutableObject)super.clone();
obj.counter=(Counter)counter.clone();
return obj;
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class MutableObjectClone
{
public static void main(String[] args)
{
MutableObject obj=new MutableObject();
obj.increase();
MutableObject clonedObj=(MutableObject)obj.clone();
clonedObj.increase();
obj.increase();
obj.increase();
System.out.println("clonedObj.getValue(): "+clonedObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
}
}

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

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

示例如下:

 public class UserException
{
private String name;
private String email; public User(String name,String email)
{
this.name=name;
this.email=email;
}
public User(User user)
{
this.name=user.getName();
this.email=user.getEmail();
} public String getName()
{
return this.name;
}
public String getEmail()
{
return this.email;
}
}

(原)java中对象复制、==、equals的更多相关文章

  1. Java中对象的深复制和浅复制详解

    1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...

  2. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  3. JAVA中浅复制与深复制

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...

  4. 深入分析Java中的 == 和equals

    关于Java中的 == 和equals的解释请看这位博主的文章 :http://www.cnblogs.com/dolphin0520/p/3592500.html 以下是我对这篇文章的一些扩展. 对 ...

  5. 2)Java中的==和equals

    Java中的==和equals   1.如果比较对象是值变量:只用==   2.如果比较对象是引用型变量:      ==:比较两个引用是不是指向同一个对象实例.      equals:       ...

  6. java中的==和equals的区别

    关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...

  7. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  8. java中的==、equals()、hashCode()源码分析(转载)

    在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...

  9. java中的==、equals()、hashCode()

    java中的==.equals().hashCode()源码分析 在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中 ...

随机推荐

  1. C/C++ 常用工具集

    1. c++filt  //注意:就是这个名字 "c++file". 能把c++的函数签名转换成代码形参格式: 如:# c++filt _ZNSt4priv17_Rb_tree_i ...

  2. Java虚拟机工作原理详解 (一)

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...

  3. String类常用方法。

    一,字符数组与字符串. 一个字符串可以变成一个字符数组,同样,一个字符数组可以变成一个字符串. 在String类中提供了以下操作方法. 1)将字符串变成字符数组:public char[] toCha ...

  4. 04SpringMvc_映射器_BeanNameUrlHanderMapping

    这篇文章我们讲的是映射器,映射器的作用是什么样的请求交给Action,如果我们没有在xml配置文件中进行配置,默认的就是BeanNameUrlHanderMapping. 我们讲一个案例增加用户的案例 ...

  5. hp_jetdirect 9100漏洞检测

    #-*-coding=utf8-*- import socket import sys def main(): if len(sys.argv)<=1: print('Parameters er ...

  6. PHP基础16:多维数组

    <?php //1.PHP-两维数组 $cars=array ( array("Volvo",22,18), array("BMW",15,13), ar ...

  7. C#中小数点后保留两位小数,四舍五入的函数及使用方法

    Math.Round(45.367,2)     //Returns   45.37 Math.Round(45.365,2)     //Returns   45.36 C#中的Round()不是我 ...

  8. 验证视图状态 MAC 失败的解决办法

    昨天用户反应系统中有问题,问题就在于翻页的时候,系统会报以下错误.但是我们的系统已经上线1年多了,从来没出现过错误,怎么会出现错误呢?于是开始检测,查找原因. 1. 出错提示 “/”应用程序中的服务器 ...

  9. DIV相关的操作总结

    由于有时候需要做网站项目,遇到CSS的问题总是需要百度或者google一下,比较麻烦,索性今天就来总结一下,这里就拿div开刀先. DIV在HTML前端页面布局中,非常重要,我们经常遇到的问题是:DI ...

  10. JavaScript原型链和instanceof运算符的暧昧关系

    时间回到两个月前,简单地理了理原型链.prototype以及__proto__之间的乱七八糟的关系,同时也简单了解了下typeof和instanceof两个运算符,但是,anyway,试试以下两题: ...