(原)java中对象复制、==、equals
对于基本数据类型而言,即如下八种基本数据类型,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的更多相关文章
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- JAVA中浅复制与深复制
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- 深入分析Java中的 == 和equals
关于Java中的 == 和equals的解释请看这位博主的文章 :http://www.cnblogs.com/dolphin0520/p/3592500.html 以下是我对这篇文章的一些扩展. 对 ...
- 2)Java中的==和equals
Java中的==和equals 1.如果比较对象是值变量:只用== 2.如果比较对象是引用型变量: ==:比较两个引用是不是指向同一个对象实例. equals: ...
- java中的==和equals的区别
关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...
- java中数组复制的两种方式
在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...
- java中的==、equals()、hashCode()源码分析(转载)
在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...
- java中的==、equals()、hashCode()
java中的==.equals().hashCode()源码分析 在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中 ...
随机推荐
- Android事件分发机制完全解析,带你从源码的角度彻底理解
Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作.所有这些都构成了Android中的事件响应.总的来说,所有的事件都 ...
- ajax载入数据是小细节
今天看了一个点子: 在 ajax 导入数据的 div中添加一些样式,比如:我们正紧急抢救 增加趣味性,有解决数据卡壳问题
- 11Mybatis_mybatis开发Dao的方法
在介绍开发Dao的方法之前先介绍下SqlSession. 1.先介绍一下SqlSessionFactoryBuilder:通过SqlSessionFactoryBuilder创建会话工厂SqlSess ...
- R 分类进行数值处理
主要Mark一下R程序中,分类进行数值计算的情况. 1.aggregate函数 有数据框case,列名分别a,b,c,d,e,f (1)根据一列对另一列求和:根据a,对d求和 sum1 <- a ...
- python 遗传算法精简版
精简版遗传算法,算法中仅采用变异算子而没有使用交叉算子,但是进化依然很有效 from string import ascii_lowercase from random import choice, ...
- 基于IHttpAsyncHandler的TCP收发器
上一篇文章中,我们提到使用IHttpAsyncHandler来进行UDP的收发操作.由于UDP模型比较简单,所以运行没什么问题.这一篇我主要是使用IHttpAsyncHandler来进行TCP的收发操 ...
- ActionBar在Android2.x的实现,类似新版微信界面。
ActionBar完美兼容Android4.x的机型,虽然现在Android2.x的系统越来越少,还有有一部分人使用的仍是2.x的系统,所以我们还得考虑着兼容性问题. 对比图: Test例子与微信的对 ...
- 20145311利用gdb调试汇编代码
利用GDB调试汇编代码 首先编写c语言原代码,我使用的是同学分析过的代码 #include<stdio.h>short addend1 = 1;static int addend2 = 2 ...
- [NOIP2016-day1-T2]天天爱跑步running_题解
题目来源:http://www.lydsy.com/JudgeOnline/problem.php?id=4719 镇楼图: noip滚粗后..订正的第一题. 题目大意: 有若干条路径在一棵树上,问每 ...
- web.xml配置文件
一.web.xml里面的标签 <display-name> <context-param> <listener> <filter> 和 <filt ...